<commit_before>'use strict';

var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');

var browserSync = require('browser-sync');
var browserSyncSpa = require('browser-sync-spa');

var util = require('util');

var proxyMiddleware = require('http-proxy-middleware');

function browserSyncInit(baseDir, browser) {
  browser = browser === undefined ? 'default' : browser;

  var routes = null;
  if(baseDir === conf.paths.src || (util.isArray(baseDir) && baseDir.indexOf(conf.paths.src) !== -1)) {
    routes = {
      '/bower_components': 'bower_components'
    };
  }

  var server = {
    baseDir: baseDir,
    routes: routes
  };

  /*
   * You can add a proxy to your backend by uncommenting the line below.
   * You just have to configure a context which will we redirected and the target url.
   * Example: $http.get('/users') requests will be automatically proxified.
   *
   * For more details and option, https://github.com/chimurai/http-proxy-middleware/blob/v0.9.0/README.md
   */
  // server.middleware = proxyMiddleware('/users', {target: 'http://jsonplaceholder.typicode.com', changeOrigin: true});

  browserSync.instance = browserSync.init({
    startPath: '/',
    server: server,
    browser: browser
  });
}

browserSync.use(browserSyncSpa({
  selector: '[ng-app]'// Only needed for angular apps
}));

gulp.task('serve', ['watch'], function () {
  browserSyncInit([path.join(conf.paths.tmp, '/serve'), conf.paths.src]);
});

gulp.task('serve:dist', ['build'], function () {
  browserSyncInit(conf.paths.dist);
});

gulp.task('serve:e2e', ['inject'], function () {
  browserSyncInit([conf.paths.tmp + '/serve', conf.paths.src], []);
});

gulp.task('serve:e2e-dist', ['build'], function () {
  browserSyncInit(conf.paths.dist, []);
});
<commit_msg>Add tunneling to help test<commit_after>'use strict';

var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');

var browserSync = require('browser-sync');
var browserSyncSpa = require('browser-sync-spa');

var util = require('util');

var proxyMiddleware = require('http-proxy-middleware');

function browserSyncInit(baseDir, browser) {
  browser = browser === undefined ? 'default' : browser;

  var routes = null;
  if(baseDir === conf.paths.src || (util.isArray(baseDir) && baseDir.indexOf(conf.paths.src) !== -1)) {
    routes = {
      '/bower_components': 'bower_components'
    };
  }

  var server = {
    baseDir: baseDir,
    routes: routes
  };

  /*
   * You can add a proxy to your backend by uncommenting the line below.
   * You just have to configure a context which will we redirected and the target url.
   * Example: $http.get('/users') requests will be automatically proxified.
   *
   * For more details and option, https://github.com/chimurai/http-proxy-middleware/blob/v0.9.0/README.md
   */
  // server.middleware = proxyMiddleware('/users', {target: 'http://jsonplaceholder.typicode.com', changeOrigin: true});

  browserSync.instance = browserSync.init({
    startPath: '/',
    server: server,
    browser: browser,
    tunnel: true
  });
}

browserSync.use(browserSyncSpa({
  selector: '[ng-app]'// Only needed for angular apps
}));

gulp.task('serve', ['watch'], function () {
  browserSyncInit([path.join(conf.paths.tmp, '/serve'), conf.paths.src]);
});

gulp.task('serve:dist', ['build'], function () {
  browserSyncInit(conf.paths.dist);
});

gulp.task('serve:e2e', ['inject'], function () {
  browserSyncInit([conf.paths.tmp + '/serve', conf.paths.src], []);
});

gulp.task('serve:e2e-dist', ['build'], function () {
  browserSyncInit(conf.paths.dist, []);
});
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');

var browserSync = require('browser-sync');
var browserSyncSpa = require('browser-sync-spa');

var util = require('util');

var proxyMiddleware = require('http-proxy-middleware');
var exec = require('child_process').exec;
var $ = require('gulp-load-plugins')({});

function browserSyncInit(baseDir, browser) {
  browser = browser === undefined ? 'default' : browser;

  var routes = null;
  if(baseDir === conf.paths.src || (util.isArray(baseDir) && baseDir.indexOf(conf.paths.src) !== -1)) {
    routes = {
      '/bower_components': 'bower_components'
    };
  }

  var server = {
    baseDir: baseDir,
    routes: routes
  };

  /*
   * You can add a proxy to your backend by uncommenting the line below.
   * You just have to configure a context which will we redirected and the target url.
   * Example: $http.get('/users') requests will be automatically proxified.
   *
   * For more details and option, https://github.com/chimurai/http-proxy-middleware/blob/v0.9.0/README.md
   */
  // server.middleware = proxyMiddleware('/users', {target: 'http://jsonplaceholder.typicode.com', changeOrigin: true});

  browserSync.instance = browserSync.init({
    startPath: '/',
    server: server,
    browser: browser
  });
}

browserSync.use(browserSyncSpa({
  selector: '[ng-app]'// Only needed for angular apps
}));

gulp.task('serve', ['watch'], function () {
  browserSyncInit([path.join(conf.paths.tmp, '/serve'), conf.paths.src]);
});

gulp.task('serve:dist', ['build'], function () {
  browserSyncInit(conf.paths.dist);
});

gulp.task('serve:e2e', ['inject'], function () {
  browserSyncInit([conf.paths.tmp + '/serve', conf.paths.src], []);
});

gulp.task('serve:e2e-dist', ['build'], function () {
  browserSyncInit(conf.paths.dist, []);
});
gulp.task('gh',['build'],function(){
  exec('git checkout gh-pages', function (err, stdout, stderr) {
      console.log("checkout output:: "+stdout);
      console.log("checkout error:: "+stderr);
    $.del(['scripts/', 'assets/','styles/','fonts/','maps/']);
   /* gulp.src('./dist/!**!/!*').pipe(gulp.dest('./'))
      gulp.src('./dist/!**!/!*').pipe(gulp.dest('./'))*/
  });
});
<commit_msg>added new update<commit_after>'use strict';

var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');

var browserSync = require('browser-sync');
var browserSyncSpa = require('browser-sync-spa');

var util = require('util');

var proxyMiddleware = require('http-proxy-middleware');
var exec = require('child_process').exec;
var $ = require('gulp-load-plugins')({
  pattern: ['gulp-*', 'main-bower-files', 'uglify-save-license', 'del']
});

function browserSyncInit(baseDir, browser) {
  browser = browser === undefined ? 'default' : browser;

  var routes = null;
  if(baseDir === conf.paths.src || (util.isArray(baseDir) && baseDir.indexOf(conf.paths.src) !== -1)) {
    routes = {
      '/bower_components': 'bower_components'
    };
  }

  var server = {
    baseDir: baseDir,
    routes: routes
  };

  /*
   * You can add a proxy to your backend by uncommenting the line below.
   * You just have to configure a context which will we redirected and the target url.
   * Example: $http.get('/users') requests will be automatically proxified.
   *
   * For more details and option, https://github.com/chimurai/http-proxy-middleware/blob/v0.9.0/README.md
   */
  // server.middleware = proxyMiddleware('/users', {target: 'http://jsonplaceholder.typicode.com', changeOrigin: true});

  browserSync.instance = browserSync.init({
    startPath: '/',
    server: server,
    browser: browser
  });
}

browserSync.use(browserSyncSpa({
  selector: '[ng-app]'// Only needed for angular apps
}));

gulp.task('serve', ['watch'], function () {
  browserSyncInit([path.join(conf.paths.tmp, '/serve'), conf.paths.src]);
});

gulp.task('serve:dist', ['build'], function () {
  browserSyncInit(conf.paths.dist);
});

gulp.task('serve:e2e', ['inject'], function () {
  browserSyncInit([conf.paths.tmp + '/serve', conf.paths.src], []);
});

gulp.task('serve:e2e-dist', ['build'], function () {
  browserSyncInit(conf.paths.dist, []);
});
gulp.task('gh',['build'],function(){
  exec('git checkout gh-pages', function (err, stdout, stderr) {
      console.log("checkout output:: "+stdout);
      console.log("checkout error:: "+stderr);
    $.del(['scripts/', 'assets/','styles/','fonts/','maps/']);
   /* gulp.src('./dist/!**!/!*').pipe(gulp.dest('./'))
      gulp.src('./dist/!**!/!*').pipe(gulp.dest('./'))*/
  });
});
<|endoftext|>


<commit_before>var app = require(global.settings.app_root + '/app/controllers/app')();
var assert = require('../../support/assert');
var sqlite = require('sqlite3');

describe.only('spatialite query',function(){

    it('returns a valid sqlite database', function(done){
        assert.response(app, {
            url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4%20LIMIT%201&format=spatialite',
            headers: {host: 'vizzuality.cartodb.com'},
            method: 'GET'
        },{ }, function(res) {
            assert.equal(res.statusCode, 200, res.body);
            assert.equal(res.headers["content-type"], "application/x-sqlite3; charset=utf-8");
            var db = new sqlite.Database(res.body);
            var qr = db.get("PRAGMA database_list", function(err){
                assert.equal(err, null);
                done();
            });
            assert.notEqual(qr, undefined);
        });

    });

    it('different file name', function(done){
        assert.response(app, {
            url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4%20LIMIT%201&format=spatialite&filename=manolo',
            headers: {host: 'vizzuality.cartodb.com'},
            method: 'GET'
        },{ }, function(res) {
            assert.equal(res.headers["content-type"], "application/x-sqlite3; charset=utf-8");
            assert.notEqual(res.headers["content-disposition"].indexOf("manolo.sqlite"), -1);
            done();
        });
    });

    it('gets database schema', function(done){
        assert.response(app, {
            url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4%20LIMIT%201&format=spatialite',
            headers: {host: 'vizzuality.cartodb.com'},
            method: 'GET'
        },{ }, function(res) {
            var db = new sqlite.Database(res.body);
            var schemaQuery = "SELECT name, sql FROM sqlite_master WHERE type='table' ORDER BY name";
            var qr = db.get(schemaQuery, function(err){
                assert.equal(err, null);
                done();
            });
            assert.notEqual(qr, undefined);
        });
    });
});
<commit_msg>removes only from test call<commit_after>var app = require(global.settings.app_root + '/app/controllers/app')();
var assert = require('../../support/assert');
var sqlite = require('sqlite3');

describe('spatialite query', function(){

    it('returns a valid sqlite database', function(done){
        assert.response(app, {
            url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4%20LIMIT%201&format=spatialite',
            headers: {host: 'vizzuality.cartodb.com'},
            method: 'GET'
        },{ }, function(res) {
            assert.equal(res.statusCode, 200, res.body);
            assert.equal(res.headers["content-type"], "application/x-sqlite3; charset=utf-8");
            var db = new sqlite.Database(res.body);
            var qr = db.get("PRAGMA database_list", function(err){
                assert.equal(err, null);
                done();
            });
            assert.notEqual(qr, undefined);
        });

    });

    it('different file name', function(done){
        assert.response(app, {
            url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4%20LIMIT%201&format=spatialite&filename=manolo',
            headers: {host: 'vizzuality.cartodb.com'},
            method: 'GET'
        },{ }, function(res) {
            assert.equal(res.headers["content-type"], "application/x-sqlite3; charset=utf-8");
            assert.notEqual(res.headers["content-disposition"].indexOf("manolo.sqlite"), -1);
            done();
        });
    });

    it('gets database schema', function(done){
        assert.response(app, {
            url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4%20LIMIT%201&format=spatialite',
            headers: {host: 'vizzuality.cartodb.com'},
            method: 'GET'
        },{ }, function(res) {
            var db = new sqlite.Database(res.body);
            var schemaQuery = "SELECT name, sql FROM sqlite_master WHERE type='table' ORDER BY name";
            var qr = db.get(schemaQuery, function(err){
                assert.equal(err, null);
                done();
            });
            assert.notEqual(qr, undefined);
        });
    });
});
<|endoftext|>


<commit_before>const {
  getSelectorForElementWithText,
  getButtonWithText,
  getMetaListItemValueSelector,
} = require('../../helpers/selectors')

const getFilterTagRemoveBtnSelector = (text) => getSelectorForElementWithText(
  text,
  {
    el: '//span',
    className: 'c-collection__filter-label',
    child: '/following-sibling::a',
  }
)

module.exports = {
  url: process.env.QA_HOST + '/events',
  props: {},
  elements: {
    h1Element: '.c-local-header__heading',
    addEventButton: getButtonWithText('Add event'),
    sortBy: '#field-sortby',
    xhrTargetElement: '#xhr-outlet',
  },
  sections: {
    filterTags: {
      selector: '.c-collection__filter-summary',
      elements: {
        eventName: getFilterTagRemoveBtnSelector('Event name'),
        organiser: getFilterTagRemoveBtnSelector('Organiser'),
        eventType: getFilterTagRemoveBtnSelector('Type of event'),
        country: getFilterTagRemoveBtnSelector('Country'),
        fromDate: getFilterTagRemoveBtnSelector('From'),
      },
    },
    firstEventInList: {
      selector: '.c-entity-list li:first-child',
      elements: {
        header: {
          selector: '.c-entity__header a',
        },
        eventType: getMetaListItemValueSelector('Type'),
        country: getMetaListItemValueSelector('Country'),
        ukRegion: getMetaListItemValueSelector('Region'),
        eventStart: getMetaListItemValueSelector('Begins'),
        eventEnd: getMetaListItemValueSelector('Ends'),
        organiser: getMetaListItemValueSelector('Organiser'),
        leadTeam: getMetaListItemValueSelector('Lead team'),
      },
    },
    secondEventInList: {
      selector: '.c-entity-list li:nth-child(2)',
      elements: {
        header: {
          selector: '.c-entity__header a',
        },
        eventStart: getMetaListItemValueSelector('Begins'),
      },
    },
    filters: {
      selector: '.c-collection-filters',
      elements: {
        nameInput: '#field-name',
        organiser: '[name="organiser"]',
        country: '[name="address_country"]',
        eventType: '[name="event_type"]',
        startDateAfter: '#field-start_date_after',
      },
    },
  },
}
<commit_msg>Switch to string interpolation for consistency<commit_after>const {
  getSelectorForElementWithText,
  getButtonWithText,
  getMetaListItemValueSelector,
} = require('../../helpers/selectors')

const getFilterTagRemoveBtnSelector = (text) => getSelectorForElementWithText(
  text,
  {
    el: '//span',
    className: 'c-collection__filter-label',
    child: '/following-sibling::a',
  }
)

module.exports = {
  url: `${process.env.QA_HOST}/events`,
  props: {},
  elements: {
    h1Element: '.c-local-header__heading',
    addEventButton: getButtonWithText('Add event'),
    sortBy: '#field-sortby',
    xhrTargetElement: '#xhr-outlet',
  },
  sections: {
    filterTags: {
      selector: '.c-collection__filter-summary',
      elements: {
        eventName: getFilterTagRemoveBtnSelector('Event name'),
        organiser: getFilterTagRemoveBtnSelector('Organiser'),
        eventType: getFilterTagRemoveBtnSelector('Type of event'),
        country: getFilterTagRemoveBtnSelector('Country'),
        fromDate: getFilterTagRemoveBtnSelector('From'),
      },
    },
    firstEventInList: {
      selector: '.c-entity-list li:first-child',
      elements: {
        header: {
          selector: '.c-entity__header a',
        },
        eventType: getMetaListItemValueSelector('Type'),
        country: getMetaListItemValueSelector('Country'),
        ukRegion: getMetaListItemValueSelector('Region'),
        eventStart: getMetaListItemValueSelector('Begins'),
        eventEnd: getMetaListItemValueSelector('Ends'),
        organiser: getMetaListItemValueSelector('Organiser'),
        leadTeam: getMetaListItemValueSelector('Lead team'),
      },
    },
    secondEventInList: {
      selector: '.c-entity-list li:nth-child(2)',
      elements: {
        header: {
          selector: '.c-entity__header a',
        },
        eventStart: getMetaListItemValueSelector('Begins'),
      },
    },
    filters: {
      selector: '.c-collection-filters',
      elements: {
        nameInput: '#field-name',
        organiser: '[name="organiser"]',
        country: '[name="address_country"]',
        eventType: '[name="event_type"]',
        startDateAfter: '#field-start_date_after',
      },
    },
  },
}
<|endoftext|>


<commit_before>import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';

import BranchInfoRow  from '../../src/container/BranchInfoRow';

describe('Dashboard branch component', () => {
    const BRANCH_NAME = 'someBranchName';
    const branch = {name: BRANCH_NAME};
    const dashComp = shallow(
        <BranchInfoRow branch={branch} />
    );

    it('should render to a <tr> without className per default', () => {
        expect(dashComp.type()).to.equal('tr');
    });

    xit('should have class warning', () => {
        expect(dashComp.props().className).to.equal('warning');
    });

    it('should have 3 columns', () => {
        const columns = dashComp.find('td');

        expect(columns).to.have.length(3);
    });

    it('first column should contain a link with text containing the branchName', () => {
        const firstColumn = dashComp.childAt(0);
        const aLink = firstColumn.find('a');

        expect(aLink.props().children).to.equal(BRANCH_NAME);
    });

});
<commit_msg>remove waste: skipped, ignored unit test<commit_after>import React from 'react';
import {
    expect
}
from 'chai';
import {
    shallow
}
from 'enzyme';

import BranchInfoRow from '../../src/container/BranchInfoRow';

describe('Dashboard branch component', () => {
    const BRANCH_NAME = 'someBranchName';
    const branch = {
        name: BRANCH_NAME
    };
    const dashComp = shallow( < BranchInfoRow branch = {
            branch
        }
        />
    );

    it('should render to a <tr> without className per default', () => {
        expect(dashComp.type()).to.equal('tr');
    });

    it('should have 3 columns', () => {
        const columns = dashComp.find('td');

        expect(columns).to.have.length(3);
    });

    it(
        'first column should contain a link with text containing the branchName', () => {
            const firstColumn = dashComp.childAt(0);
            const aLink = firstColumn.find('a');

            expect(aLink.props().children).to.equal(BRANCH_NAME);
        });

});
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import {mount} from 'enzyme';
import {Provider} from 'react-redux';
import {genNotification, mockStore} from '../fixtures';
import {Timer} from '../../src/helpers';
import {types, removeNotification} from '../../src/store/notifications';
import css from '../../src/themes/wybo/styles/styles.scss';
import ConnectNotification, {Notification} from '../../src/components/Notification';
import {STATUS, POSITIONS} from '../../src/constants';
import {ExpectedNotification} from '../fixtures/components';
import {notificationClassName as className} from '../../src/themes/wybo';
describe('<Notification/>', () => {
  let notification = null;
  let store = null;

  // Other props for Notification component
  const otherProps = {
    removeNotification
  };

  beforeEach('generate a new notification and init store', () => {
    notification = genNotification();
    store = mockStore({notifications: []});
  });

  it('should mount with initial state', () => {
    // state component will be init without timer because notification have buttons
    let wrapper = mount(
      <Notification key={notification.id} className={className} notification={notification}
        {...otherProps}/>
    );
    expect(wrapper.state().timer).toEqual(null);
    // state component will be init with timer because notification doesn't have buttons
    notification.buttons = [];
    wrapper = mount(
      <Notification key={notification.id} className={className} notification={notification}
        {...otherProps}/>
    );
    expect(wrapper.state().timer).toBeA(Timer);
  });

  it('should update state when receiving new props', () => {
    // state component will be init without timer because notification have buttons
    let wrapper = mount(
      <Notification key={notification.id} className={className} notification={notification}
        {...otherProps}/>
    );
    expect(wrapper.state().timer).toEqual(null);
    // we delete buttons to provoke creation of a Timer
    // at `componentWillReceivedProps()` component lifecycle
    notification.buttons = [];
    wrapper.setProps(notification);
    expect(wrapper.state().timer).toBeA(Timer);
  });

  it('should render component (with title)', () => {
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    const expectedComponent = mount(
      <ExpectedNotification key={notification.id} className={className} notification={notification}
        {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (without title)', () => {
    notification.title = null;
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    const expectedComponent = mount(
      <ExpectedNotification key={notification.id} className={className} notification={notification}
        {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (with message)', () => {
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    const expectedComponent = mount(
      <ExpectedNotification key={notification.id} className={className}
        notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (with HTML message)', () => {
    // add HTML in message and allow HTML
    notification.message = `${notification.message} <b>HEY</b>`;
    notification.allowHTML = true;
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    const expectedComponent = mount(
      <ExpectedNotification key={notification.id} className={className}
        notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (without message)', () => {
    notification.message = null;
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );

    const expectedComponent = mount(
      <ExpectedNotification key={notification.id} className={className}
        notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (with 2 buttons)', () => {
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );

    const expectedComponent = mount(
      <ExpectedNotification key={notification.id} className={className}
        notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (with 1 button)', () => {
    delete notification.buttons[1];
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );

    const expectedComponent = mount(
      <ExpectedNotification key={notification.id} className={className}
        notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (without buttons)', () => {
    notification.buttons = [];
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );

    const expectedComponent = mount(
      <ExpectedNotification key={notification.id} className={className}
        notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should run onAdd() callback at componentDidMount() lifecycle', () => {
    const errorMessage = 'onAdd() callback';
    // we throw an error to capture where
    // the code has been executed before error was thrown
    notification.onAdd = () => {
      throw new Error(errorMessage);
    };
    try {
      mount(
        <Provider store={store}>
          <ConnectNotification key={notification.id} className={className}
            notification={notification}/>
        </Provider>
      );
    }
    catch (error) {
      expect(error.stack).toMatch(/onAdd[\s\S]*?componentDidMount/);
      expect(error.message).toEqual(errorMessage);
    }
    // and we update function to check that
    // component mount without any error
    notification.onAdd = () => {
      return 0;
    };
    mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
  });

  it('should run onRemove() callback at componentWillUnmount() lifecycle', () => {
    const errorMessage = 'onRemove() callback';
    // we throw an error to capture where
    // the code has been executed before error was thrown
    notification.onRemove = () => {
      throw new Error(errorMessage);
    };
    let wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    try {
      wrapper.unmount();
    }
    catch (error) {
      expect(error.stack).toMatch(/onRemove[\s\S]*?componentWillUnmount/);
      expect(error.message).toEqual(errorMessage);
    }
    // and we update function without `throw` call to check that
    // component unmount without any error
    notification.onRemove = () => {
      return 0;
    };
    wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    wrapper.unmount();
  });

  it('should create an action to remove the notification ' +
    'when it is clicked', () => {
    notification.dismissible = true;
    notification.buttons = [];
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    wrapper.find(ConnectNotification).simulate('click');
    const expectedAction = {
      type: types.REMOVE_NOTIFICATION,
      payload: notification.id
    };
    expect(store.getActions()).toEqual([expectedAction]);
  });

  it('should create an action to remove the notification ' +
    'when a action button is clicked (dismissible : false)', () => {
    // we set `dismissible` to `false` to be sure
    // that dismissible is ignored in this case
    notification.dismissible = false;
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    wrapper.find(`.${css['notification-button']}`).first().simulate('click');
    const expectedAction = {
      type: types.REMOVE_NOTIFICATION,
      payload: notification.id
    };
    expect(store.getActions()).toEqual([expectedAction]);
  });

  it('should create an action to remove the notification after ' +
    '`dismissAfter` duration', (done) => {
    notification.dismissAfter = 10;
    // remove buttons otherwise `remove()` is not called after `dismissAfter` duration
    notification.buttons = [];
    mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    const expectedAction = {
      type: types.REMOVE_NOTIFICATION,
      payload: notification.id
    };
    expect(store.getActions()).toEqual([]);
    setTimeout(() => {
      expect(store.getActions()).toEqual([expectedAction]);
      done();
    }, 15);
  });

  it('should not create an action to remove the notification ' +
    'when it is clicked (dismissible : false)', () => {
    notification.dismissible = false;
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    wrapper.find(ConnectNotification).simulate('click');
    expect(store.getActions()).toEqual([]);
  });

  it('should not create an action to remove the notification ' +
    'when it is clicked (no buttons)', (done) => {
    // we set `dismissible` to `true` to be sure that
    // `buttons.length` must equals `0` to allow removing
    // same thing for `dismissAfter`
    notification.dismissible = true;
    notification.dismissAfter = 5;
    let wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    wrapper.find(ConnectNotification).simulate('click');
    expect(store.getActions()).toEqual([]);
    // we remove an button and test it again
    notification.buttons = notification.buttons.slice(0, 1);
    wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    wrapper.find(ConnectNotification).simulate('click');
    expect(store.getActions()).toEqual([]);
    // check after `dismissAfter` duration
    setTimeout(() => {
      expect(store.getActions()).toEqual([]);
      done();
    }, 10);
  });

  it('should not create an action to remove the notification after ' +
    '`dismissAfter` duration (dismissAfter = 0)', (done) => {
    notification.dismissAfter = 0;
    mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    );
    setTimeout(() => {
      expect(store.getActions()).toEqual([]);
      done();
    }, 10);
  });

  it('should not create an action to remove the notification ' +
    'while mouse is hovering it', (done) => {
    notification.dismissAfter = 10;
    notification.buttons = [];
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification key={notification.id} className={className}
          notification={notification}/>
      </Provider>
    ).find(ConnectNotification);
    const expectedAction = {
      type: types.REMOVE_NOTIFICATION,
      payload: notification.id
    };
    // hover notification after 5s
    setTimeout(() => {
      wrapper.simulate('mouseEnter');
    }, 5);
    // check 5s after `dismissAfter` duration that the store
    // is empty because mouse is hovering the notification
    setTimeout(() => {
      expect(store.getActions()).toEqual([]);
      // we leave notification
      wrapper.simulate('mouseLeave');
    }, 15);
    // and we check that the store contains an action
    setTimeout(() => {
      expect(store.getActions()).toEqual([expectedAction]);
      done();
    }, 21);
  });
});
<commit_msg>fix test for Notification component<commit_after>import React from 'react';
import {mount} from 'enzyme';
import {Provider} from 'react-redux';
import {genNotification, mockStore} from '../utils/fixtures';
import {Timer} from '../../src/helpers';
import {types, removeNotification} from '../../src/store/notifications';
import ConnectNotification, {Notification} from '../../src/components/Notification';
import {ExpectedNotification} from '../utils/expectedComponents';
import {notificationClassName as className} from '../../src/themes/wybo';

describe('<Notification/>', () => {
  let notification = null;
  let store = null;
  // these props are the same for all tests
  let otherProps = {
    className,
    removeNotification
  };

  beforeEach('generate a new notification and init store', () => {
    notification = genNotification();
    store = mockStore({notifications: []});
  });

  it('should mount with initial state', () => {
    // state component will be init without timer because notification have buttons
    let wrapper = mount(<Notification notification={notification} {...otherProps}/>);
    expect(wrapper.state().timer).toEqual(null);
    // state component will be init with timer because notification doesn't have buttons
    notification.buttons = [];
    wrapper = mount(<Notification notification={notification} {...otherProps}/>);
    expect(wrapper.state().timer).toBeA(Timer);
  });

  it('should update state when receiving new props', () => {
    // state component will be init without timer because notification have buttons
    let wrapper = mount(<Notification notification={notification} {...otherProps}/>);
    expect(wrapper.state().timer).toEqual(null);
    // we delete buttons to provoke creation of a Timer
    // at `componentWillReceivedProps()` component lifecycle
    notification.buttons = [];
    wrapper.setProps(notification);
    expect(wrapper.state().timer).toBeA(Timer);
  });

  it('should render component (with title)', () => {
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    const expectedComponent = mount(
      <ExpectedNotification notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (without title)', () => {
    notification.title = null;
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    const expectedComponent = mount(
      <ExpectedNotification notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (with message)', () => {
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    const expectedComponent = mount(
      <ExpectedNotification notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (with HTML message)', () => {
    // add HTML in message and allow HTML
    notification.message = `${notification.message} <b>HEY</b>`;
    notification.allowHTML = true;
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    const expectedComponent = mount(
      <ExpectedNotification notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (without message)', () => {
    notification.message = null;
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );

    const expectedComponent = mount(
      <ExpectedNotification notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (with 2 buttons)', () => {
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );

    const expectedComponent = mount(
      <ExpectedNotification notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (with 1 button)', () => {
    delete notification.buttons[1];
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );

    const expectedComponent = mount(
      <ExpectedNotification notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should render component (without buttons)', () => {
    notification.buttons = [];
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );

    const expectedComponent = mount(
      <ExpectedNotification notification={notification} {...otherProps}/>
    );
    expect(wrapper.html()).toEqual(expectedComponent.html());
  });

  it('should run onAdd() callback at componentDidMount() lifecycle', () => {
    const errorMessage = 'onAdd() callback';
    // we throw an error to capture where
    // the code has been executed before error was thrown
    notification.onAdd = () => {
      throw new Error(errorMessage);
    };
    try {
      mount(
        <Provider store={store}>
          <ConnectNotification notification={notification} {...otherProps}/>
        </Provider>
      );
    }
    catch (error) {
      expect(error.stack).toMatch(/onAdd[\s\S]*?componentDidMount/);
      expect(error.message).toEqual(errorMessage);
    }
    // and we update function to check that
    // component mount without any error
    notification.onAdd = () => {
      return 0;
    };
    mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
  });

  it('should run onRemove() callback at componentWillUnmount() lifecycle', () => {
    const errorMessage = 'onRemove() callback';
    // we throw an error to capture where
    // the code has been executed before error was thrown
    notification.onRemove = () => {
      throw new Error(errorMessage);
    };
    let wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    try {
      wrapper.unmount();
    }
    catch (error) {
      expect(error.stack).toMatch(/onRemove[\s\S]*?componentWillUnmount/);
      expect(error.message).toEqual(errorMessage);
    }
    // and we update function without `throw` call to check that
    // component unmount without any error
    notification.onRemove = () => {
      return 0;
    };
    wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    wrapper.unmount();
  });

  it('should create an action to remove the notification ' +
    'when it is clicked', () => {
    notification.dismissible = true;
    notification.buttons = [];
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    wrapper.find(ConnectNotification).simulate('click');
    const expectedAction = {
      type: types.REMOVE_NOTIFICATION,
      payload: notification.id
    };
    expect(store.getActions()).toEqual([expectedAction]);
  });

  it('should create an action to remove the notification ' +
    'when a action button is clicked (dismissible : false)', () => {
    // we set `dismissible` to `false` to be sure
    // that dismissible is ignored in this case
    notification.dismissible = false;
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    wrapper.find(`.${className.button}`).first().simulate('click');
    const expectedAction = {
      type: types.REMOVE_NOTIFICATION,
      payload: notification.id
    };
    expect(store.getActions()).toEqual([expectedAction]);
  });

  it('should create an action to remove the notification after ' +
    '`dismissAfter` duration', (done) => {
    notification.dismissAfter = 10;
    // remove buttons otherwise `remove()` is not called after `dismissAfter` duration
    notification.buttons = [];
    mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    const expectedAction = {
      type: types.REMOVE_NOTIFICATION,
      payload: notification.id
    };
    expect(store.getActions()).toEqual([]);
    setTimeout(() => {
      expect(store.getActions()).toEqual([expectedAction]);
      done();
    }, 15);
  });

  it('should not create an action to remove the notification ' +
    'when it is clicked (dismissible : false)', () => {
    notification.dismissible = false;
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    wrapper.find(ConnectNotification).simulate('click');
    expect(store.getActions()).toEqual([]);
  });

  it('should not create an action to remove the notification ' +
    'when it is clicked (no buttons)', (done) => {
    // we set `dismissible` to `true` to be sure that
    // `buttons.length` must equals `0` to allow removing
    // same thing for `dismissAfter`
    notification.dismissible = true;
    notification.dismissAfter = 5;
    let wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    wrapper.find(ConnectNotification).simulate('click');
    expect(store.getActions()).toEqual([]);
    // we remove an button and test it again
    notification.buttons = notification.buttons.slice(0, 1);
    wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    wrapper.find(ConnectNotification).simulate('click');
    expect(store.getActions()).toEqual([]);
    // check after `dismissAfter` duration
    setTimeout(() => {
      expect(store.getActions()).toEqual([]);
      done();
    }, 10);
  });

  it('should not create an action to remove the notification after ' +
    '`dismissAfter` duration (dismissAfter = 0)', (done) => {
    notification.dismissAfter = 0;
    mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    );
    setTimeout(() => {
      expect(store.getActions()).toEqual([]);
      done();
    }, 10);
  });

  it('should not create an action to remove the notification ' +
    'while mouse is hovering it', (done) => {
    notification.dismissAfter = 10;
    notification.buttons = [];
    const wrapper = mount(
      <Provider store={store}>
        <ConnectNotification notification={notification} {...otherProps}/>
      </Provider>
    ).find(ConnectNotification);
    const expectedAction = {
      type: types.REMOVE_NOTIFICATION,
      payload: notification.id
    };
    // hover notification after 5s
    setTimeout(() => {
      wrapper.simulate('mouseEnter');
    }, 5);
    // check 5s after `dismissAfter` duration that the store
    // is empty because mouse is hovering the notification
    setTimeout(() => {
      expect(store.getActions()).toEqual([]);
      // we leave notification
      wrapper.simulate('mouseLeave');
    }, 15);
    // and we check that the store contains an action
    setTimeout(() => {
      expect(store.getActions()).toEqual([expectedAction]);
      done();
    }, 21);
  });
});
<|endoftext|>


<commit_before>///
// TEAM PAYPR
///

var utils = require('../lib/utils.js');

var gameRunner = {
  info: {
    name: 'paypr',
    style: 1,
    handicap: 1,
    state: {
        test: "hello"
    }
},
ai: (playerState, enemiesState, gameEnvironment) => {

    var hasAmmo = playerState.ammo > 0;
    var i;
    var directionToAmmo;
    var closestAmmoPos;

    console.log("PAYPR");

    if(!playerState.custom) {
        playerState.custom = {};
    }

    //kill if possible
    if (utils.canKill(playerState, enemiesState) && playerState.ammo) {
        return 'shoot';
    }

    //find closest ammo direction
    if (gameEnvironment.ammoPosition.length > 0) {

        var minDist = Math.abs(utils.getDistance(playerState.position, gameEnvironment.ammoPosition[0]));
        closestAmmoPos = gameEnvironment.ammoPosition[0];
        directionToAmmo = utils.getDirection(
            playerState.position,
            gameEnvironment.ammoPosition[0]
        );

        for(i=1; i<gameEnvironment.ammoPosition.length; i++) {
            console.log(gameEnvironment.ammoPosition[i]);

            var testDist = Math.abs(utils.getDistance(playerState.position, gameEnvironment.ammoPosition[i]));
            console.log("comparing " + testDist + " < " + minDist);
            if(testDist < minDist) {
                console.log("testDist smaller");
                minDist = testDist;
                directionToAmmo = utils.getDirection(
                    playerState.position,
                    gameEnvironment.ammoPosition[i]
                );
                closestAmmoPos = gameEnvironment.ammoPosition[i];
            }
        }

    }

    //check to see if there are any enemies moving within direction
    var myX = playerState.position[0];
    var myY = playerState.position[1];
    var myPos = playerState.position;

    var isUp = function(myPosition, enemyPosition) {
        return myPosition[1] - enemyPosition[1] < 0;
    };

    var isDown = function(myPosition, enemyPosition) {
        return !isUp(myPosition,enemyPosition);
    };

    var isLeft = function(myPosition, enemyPosition) {
        return myPosition[0] - enemyPosition[0] > 0;
    };
    var isRight = function(myPosition, enemyPosition) {
        return !isLeft(myPosition,enemyPosition);
    };

    for(i=0; i<enemiesState.length && hasAmmo; i++) {
        var enemy = enemiesState[i];
        var enPos = enemy.position;
        var enDir = enemy.direction;

        //if they are in the same lane and not moving out of it
        //then point and FIRE
        if(enPos[0] === myX && (enDir == 'north' || enDir == 'south')) {

            if(isUp(myPos, enPos)) {
                return 'north';
            }
            else return 'south';
        }

        if(enPos[1] === myY && (enDir == 'east' || enDir == 'west')) {
            if(isLeft(myPos, enPos)) {
                return 'west';
            }
            else return 'east';
        }

        /*
        // is moving left and facing east                if moving right and facing west
        if( (enPos[0]+1 === myX && enDir == 'east') || (enPos[0]-1 === myX && enDir == 'west'))  { //is left and moving east
            if(isUp(enPos, myPos)) {
                console.log("PREDICTING ENEMY WILL BE NORTH");
                return 'north';
            }
            console.log("PREDICTING ENEMY WILL BE SOUTH")
            else return 'south';
        }
        */
    }

    //move to ammo
    // if(!hasAmmo) {
        if (directionToAmmo !== playerState.direction) {
            console.log("turning to ammo");
            return directionToAmmo;
        }
        console.log("moving to ammo");
        return 'move';
    // }

    //otherwise hunt
    if (gameEnvironment.ammoPosition.length > 0) {
        console.log("hunting");

        if(!utils.isVisible(playerState.position, closestAmmoPos, playerState.direction)) {
            if (directionToAmmo !== playerState.direction) {
                console.log("turning to ammo");
                return directionToAmmo;
            }
            console.log("moving to ammo");
            return 'move';
        }

    }

    //return utils.randomMove();
}
};

module.exports = gameRunner;<commit_msg>Hunt last player<commit_after>///
// TEAM PAYPR
///

var utils = require('../lib/utils.js');

var gameRunner = {
  info: {
    name: 'paypr',
    style: 1,
    handicap: 1,
    state: {
        test: "hello"
    }
},
ai: (playerState, enemiesState, gameEnvironment) => {

    var hasAmmo = playerState.ammo > 0;
    var i;
    var directionToAmmo;
    var closestAmmoPos;

    var enemiesLeft = 0;
    var lastEnemy;

    for(i=0; i<enemiesState.length; i++) {
        if(enemiesState[i].isAlive) {
            enemiesLeft++;
            lastEnemy = enemiesState[i];
        }
    }

    console.log("PAYPR");

    if(!playerState.custom) {
        playerState.custom = {};
    }

    //kill if possible
    if (utils.canKill(playerState, enemiesState) && playerState.ammo) {
        return 'shoot';
    }

    //find closest ammo direction
    if (gameEnvironment.ammoPosition.length > 0) {

        var minDist = Math.abs(utils.getDistance(playerState.position, gameEnvironment.ammoPosition[0]));
        closestAmmoPos = gameEnvironment.ammoPosition[0];
        directionToAmmo = utils.getDirection(
            playerState.position,
            gameEnvironment.ammoPosition[0]
        );

        for(i=1; i<gameEnvironment.ammoPosition.length; i++) {
            console.log(gameEnvironment.ammoPosition[i]);

            var testDist = Math.abs(utils.getDistance(playerState.position, gameEnvironment.ammoPosition[i]));
            console.log("comparing " + testDist + " < " + minDist);
            if(testDist < minDist) {
                console.log("testDist smaller");
                minDist = testDist;
                directionToAmmo = utils.getDirection(
                    playerState.position,
                    gameEnvironment.ammoPosition[i]
                );
                closestAmmoPos = gameEnvironment.ammoPosition[i];
            }
        }

    }

    //check to see if there are any enemies moving within direction
    var myX = playerState.position[0];
    var myY = playerState.position[1];
    var myPos = playerState.position;

    var isUp = function(myPosition, enemyPosition) {
        return myPosition[1] - enemyPosition[1] < 0;
    };

    var isDown = function(myPosition, enemyPosition) {
        return !isUp(myPosition,enemyPosition);
    };

    var isLeft = function(myPosition, enemyPosition) {
        return myPosition[0] - enemyPosition[0] > 0;
    };
    var isRight = function(myPosition, enemyPosition) {
        return !isLeft(myPosition,enemyPosition);
    };

    for(i=0; i<enemiesState.length && hasAmmo; i++) {
        var enemy = enemiesState[i];
        var enPos = enemy.position;
        var enDir = enemy.direction;

        //if they are in the same lane and not moving out of it
        //then point and FIRE
        if(enPos[0] === myX && (enDir == 'north' || enDir == 'south')) {

            if(isUp(myPos, enPos)) {
                return 'north';
            }
            else return 'south';
        }

        if(enPos[1] === myY && (enDir == 'east' || enDir == 'west')) {
            if(isLeft(myPos, enPos)) {
                return 'west';
            }
            else return 'east';
        }
        /*
        // is moving left and facing east                if moving right and facing west
        if( (enPos[0]+1 === myX && enDir == 'east') || (enPos[0]-1 === myX && enDir == 'west'))  { //is left and moving east
            if(isUp(enPos, myPos)) {
                console.log("PREDICTING ENEMY WILL BE NORTH");
                return 'north';
            }
            console.log("PREDICTING ENEMY WILL BE SOUTH")
            else return 'south';
        }
        */
    }

    /*
    if(hasAmmo) {
        var predictEnemys = [];
        for(i=0; i<enemiesState.length; i++) {
            predictEnemys.push({
                isAlive: enemiesState[i].isAlive,
                position: enemiesState[i].position
            });
        }

        for(i=0; i<predictEnemys.length; i++) {
            var enemy = predictEnemys[i];
            var enDir = enemy.direction;
            if(enDir == 'north') { predictEnemys[i].position[1]++; }
            if(enDir == 'south') { predictEnemys[i].position[1]--; }
            if(enDir == 'west') { predictEnemys[i].position[0]--; }
            if(enDir == 'east') { predictEnemys[i].position[0]++; }
        }

        var directions = ['north', 'south', 'east', 'west'];

        for(i=0; i<directions.length; i++) {
            var testPlayer = {
                position: playerState.position,
                direction: directions[i]
            };

            if(utils.canKill(testPlayer, predictEnemys)) {
                return directions[i];
            }
        }

    }
    */

    if(hasAmmo && enemiesLeft === 1) {
        //hunt the last player
        return utils.getDirection(playerState.position,lastEnemy.position);
    }

    //move to ammo
    // if(!hasAmmo) {
        if (directionToAmmo !== playerState.direction) {
            console.log("turning to ammo");
            return directionToAmmo;
        }
        console.log("moving to ammo");
        return 'move';
    // }

    //otherwise hunt
    if (gameEnvironment.ammoPosition.length > 0) {
        console.log("hunting");

        if(!utils.isVisible(playerState.position, closestAmmoPos, playerState.direction)) {
            if (directionToAmmo !== playerState.direction) {
                console.log("turning to ammo");
                return directionToAmmo;
            }
            console.log("moving to ammo");
            return 'move';
        }

    }

    //return utils.randomMove();
}
};

module.exports = gameRunner;<|endoftext|>


<commit_before>
function x3dPlot( id, data, config ) {

  if ( JSON.stringify( data ).includes( 'null' ) ) throw Error( 'Infinity or NaN in plot data' );

  function compositeRotation( first, second ) {

    var a = first[0], na = first[1];
    var b = second[0], nb = second[1];

    var dot = na[0]*nb[0] + na[1]*nb[1] + na[2]*nb[2];
    var cross = [ na[1]*nb[2] - na[2]*nb[1],
                  na[2]*nb[0] - na[0]*nb[2],
                  na[0]*nb[1] - na[1]*nb[0]  ];

    var c = 2 * Math.acos( Math.cos(a/2) * Math.cos(b/2)
                           - dot * Math.sin(a/2) * Math.sin(b/2) );

    var nc = [];
    for ( var i = 0 ; i < 3 ; i++ )
      nc[i] = na[i] * Math.sin(a/2) * Math.cos(b/2) / Math.sin(c/2)
              + nb[i] * Math.cos(a/2) * Math.sin(b/2) / Math.sin(c/2)
              - cross[i] * Math.sin(a/2) * Math.sin(b/2) / Math.sin(c/2);

    return [ c, nc ];

  }

  var frame = 'frame' in config ? config.frame : true;

  var n = 'output' in config ? config.output : '';
  var output = document.getElementById( id + 'output' + n );

  var width = output.offsetWidth;
  var height = output.offsetHeight;

  var texts = [], points = [], lines = [], surfaces = [];

  for ( var i = 0 ; i < data.length ; i++ )
    for ( var j = 0 ; j < data[i].length ; j++ ) {
      var d = data[i][j];
      if ( d.type === 'text' ) texts.push( d );
      if ( d.type === 'point' ) points.push( d );
      if ( d.type === 'line' ) lines.push( d );
      if ( d.type === 'surface' ) {
        d.vertices = roundTo( d.vertices, 3, false ); // reduce raw data size
        surfaces.push( d );
      }
    }

  var all = [];
  for ( var i = 0 ; i < texts.length ; i++ ) all.push( texts[i].point );
  for ( var i = 0 ; i < points.length ; i++ ) all.push( points[i].point );
  for ( var i = 0 ; i < lines.length ; i++ ) lines[i].points.forEach( p => all.push( p ) );
  for ( var i = 0 ; i < surfaces.length ; i++ ) surfaces[i].vertices.forEach( p => all.push( p ) );

  var xMinMax = minMax( all, 0 );
  var yMinMax = minMax( all, 1 );
  var zMinMax = minMax( all, 2 );

  var xMin = 'xMin' in config ? config.xMin : xMinMax.min;
  var yMin = 'yMin' in config ? config.yMin : yMinMax.min;
  var zMin = 'zMin' in config ? config.zMin : zMinMax.min;

  var xMax = 'xMax' in config ? config.xMax : xMinMax.max;
  var yMax = 'yMax' in config ? config.yMax : yMinMax.max;
  var zMax = 'zMax' in config ? config.zMax : zMinMax.max;

  var xRange = xMax - xMin;
  var yRange = yMax - yMin;
  var zRange = zMax - zMin;

  var xMid = ( xMax + xMin ) / 2;
  var yMid = ( yMax + yMin ) / 2;
  var zMid = ( zMax + zMin ) / 2;

  var boxHelper = [ [ [xMin,yMin,zMin],[xMax,yMin,zMin] ],
                    [ [xMin,yMin,zMin],[xMin,yMax,zMin] ],
                    [ [xMin,yMin,zMin],[xMin,yMin,zMax] ],
                    [ [xMax,yMin,zMin],[xMax,yMax,zMin] ],
                    [ [xMax,yMin,zMin],[xMax,yMin,zMax] ],
                    [ [xMin,yMax,zMin],[xMax,yMax,zMin] ],
                    [ [xMin,yMax,zMin],[xMin,yMax,zMax] ],
                    [ [xMin,yMin,zMax],[xMax,yMin,zMax] ],
                    [ [xMin,yMin,zMax],[xMin,yMax,zMax] ],
                    [ [xMax,yMax,zMin],[xMax,yMax,zMax] ],
                    [ [xMax,yMin,zMax],[xMax,yMax,zMax] ],
                    [ [xMin,yMax,zMax],[xMax,yMax,zMax] ] ];

  // default orientation is looking down z-axis, even after displacement
  // need to rotate viewpoint back to origin with composite orientation

  var zRotation = [ Math.PI/2 + Math.atan(yRange/xRange), [ 0, 0, 1 ] ];

  var norm1 = Math.sqrt( xRange**2 + yRange**2 + zRange**2 );
  var norm2 = Math.sqrt( xRange**2 + yRange**2 );

  var xyRotation = [ Math.acos( zRange/norm1 ),
                               [ -yRange/norm2, xRange/norm2, 0 ] ];

  var cr = compositeRotation( zRotation, xyRotation );

  var x3d = `
<X3D width="${width}" height="${height}">
<Scene>
<Background skyColor="1 1 1"></Background>
<Viewpoint position="${xRange+xMid} ${yRange+yMid} ${zRange+zMid}"
           orientation="${cr[1].join(' ')} ${cr[0]}"
           centerOfRotation="${xMid} ${yMid} ${zMid}"></Viewpoint>`;

  if ( frame ) x3d += `
<Shape>
<Appearance><Material emissiveColor='0 0 0'></Material></Appearance>
<LineSet vertexCount='2 2 2 2 2 2 2 2 2 2 2 2'>
<Coordinate point="${boxHelper.map(a => a[0].concat(a[1]).join(' ')).join(',')}"></Coordinate>
</LineSet>
</Shape>`;

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

    var s = surfaces[i];

    // remove faces completely outside vertical range
    for ( var j = s.faces.length - 1 ; j >= 0 ; j-- ) {
      var f = s.faces[j];
      var check = true;
      f.forEach( index => check = check && s.vertices[index][2] < zMin );
      if ( check ) s.faces.splice( j, 1 );
      var check = true;
      f.forEach( index => check = check && s.vertices[index][2] > zMax );
      if ( check ) s.faces.splice( j, 1 );
    }

    // constrain vertices to vertical range
    for ( var j = 0 ; j < s.vertices.length ; j++ ) {
      if ( s.vertices[j][2] < zMin ) s.vertices[j][2] = zMin;
      if ( s.vertices[j][2] > zMax ) s.vertices[j][2] = zMax;
    }

    var indices = '';
    for ( var j = 0 ; j < s.faces.length ; j++ )
      indices += s.faces[j].join(' ') + ' -1 ';

    var points = '';
    for ( var j = 0 ; j < s.vertices.length ; j++ )
      points += s.vertices[j].join(' ') + ' ';

    var p = document.createElement( 'p' );
    p.style.color = s.options.color;
    var rgb = p.style.color.replace( /[^\d,]/g, '' ).split(',');
    rgb.forEach( (e,i,a) => a[i] /= 255 );
    var color = rgb.join(' ');

    x3d += `
<Shape>
<Appearance>
<TwoSidedMaterial diffuseColor="${color}" transparency="${1-s.options.opacity}"></TwoSidedMaterial>
</Appearance>
<IndexedFaceSet creaseAngle="1.57" solid='false' coordIndex="${indices}">
<Coordinate point="${points}"></Coordinate>`;

    if ( 'colors' in s.options ) {
      var colors = '';
      for ( var j = 0 ; j < s.options.colors.length ; j++ ) {
        p.style.color = s.options.colors[j];
        rgb = p.style.color.replace( /[^\d,]/g, '' ).split(',');
        rgb.forEach( (e,i,a) => a[i] /= 255 );
        rgb = roundTo( rgb, 3 );
        colors +=  rgb.join(' ') + ' ';
      }
      x3d += `
<Color color="${colors}"></Color>`;
    }

    x3d += `
</IndexedFaceSet>
</Shape>`;

  }

  x3d += `
</Scene>
</X3D>`;

  if ( config.saveAsXML ) {

    var xml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "http://www.web3d.org/specifications/x3d-3.3.dtd">
${x3d}`;

    var blob = new Blob( [ xml ] );
    var a = document.body.appendChild( document.createElement( 'a' ) );
    a.href = window.URL.createObjectURL( blob );
    a.download = 'scene.xml';
    a.click();

  }

  var stylesheet = config.viewer === 'x3dom' ?
`<link rel="stylesheet" type="text/css" href="https://www.x3dom.org/download/x3dom.css">` :
`<link rel="stylesheet" type="text/css" href="https://code.create3000.de/x_ite/4.6.9/dist/x_ite.css"/>`;

  var script = config.viewer === 'x3dom' ?
`<script src="https://www.x3dom.org/download/x3dom.js"></script>` :
`
`;

  var html = `

<title></title>
<meta charset="utf-8">
${stylesheet}

${script}

<X3DCanvas style="width: ${width}px; height: ${height}px">
${x3d}
</X3DCanvas>

`;

  var border = config.no3DBorder ? 'none' : '1px solid black';

  return ``;

}

<commit_msg>disable straighten horizon<commit_after>
function x3dPlot( id, data, config ) {

  if ( JSON.stringify( data ).includes( 'null' ) ) throw Error( 'Infinity or NaN in plot data' );

  function compositeRotation( first, second ) {

    var a = first[0], na = first[1];
    var b = second[0], nb = second[1];

    var dot = na[0]*nb[0] + na[1]*nb[1] + na[2]*nb[2];
    var cross = [ na[1]*nb[2] - na[2]*nb[1],
                  na[2]*nb[0] - na[0]*nb[2],
                  na[0]*nb[1] - na[1]*nb[0]  ];

    var c = 2 * Math.acos( Math.cos(a/2) * Math.cos(b/2)
                           - dot * Math.sin(a/2) * Math.sin(b/2) );

    var nc = [];
    for ( var i = 0 ; i < 3 ; i++ )
      nc[i] = na[i] * Math.sin(a/2) * Math.cos(b/2) / Math.sin(c/2)
              + nb[i] * Math.cos(a/2) * Math.sin(b/2) / Math.sin(c/2)
              - cross[i] * Math.sin(a/2) * Math.sin(b/2) / Math.sin(c/2);

    return [ c, nc ];

  }

  var frame = 'frame' in config ? config.frame : true;

  var n = 'output' in config ? config.output : '';
  var output = document.getElementById( id + 'output' + n );

  var width = output.offsetWidth;
  var height = output.offsetHeight;

  var texts = [], points = [], lines = [], surfaces = [];

  for ( var i = 0 ; i < data.length ; i++ )
    for ( var j = 0 ; j < data[i].length ; j++ ) {
      var d = data[i][j];
      if ( d.type === 'text' ) texts.push( d );
      if ( d.type === 'point' ) points.push( d );
      if ( d.type === 'line' ) lines.push( d );
      if ( d.type === 'surface' ) {
        d.vertices = roundTo( d.vertices, 3, false ); // reduce raw data size
        surfaces.push( d );
      }
    }

  var all = [];
  for ( var i = 0 ; i < texts.length ; i++ ) all.push( texts[i].point );
  for ( var i = 0 ; i < points.length ; i++ ) all.push( points[i].point );
  for ( var i = 0 ; i < lines.length ; i++ ) lines[i].points.forEach( p => all.push( p ) );
  for ( var i = 0 ; i < surfaces.length ; i++ ) surfaces[i].vertices.forEach( p => all.push( p ) );

  var xMinMax = minMax( all, 0 );
  var yMinMax = minMax( all, 1 );
  var zMinMax = minMax( all, 2 );

  var xMin = 'xMin' in config ? config.xMin : xMinMax.min;
  var yMin = 'yMin' in config ? config.yMin : yMinMax.min;
  var zMin = 'zMin' in config ? config.zMin : zMinMax.min;

  var xMax = 'xMax' in config ? config.xMax : xMinMax.max;
  var yMax = 'yMax' in config ? config.yMax : yMinMax.max;
  var zMax = 'zMax' in config ? config.zMax : zMinMax.max;

  var xRange = xMax - xMin;
  var yRange = yMax - yMin;
  var zRange = zMax - zMin;

  var xMid = ( xMax + xMin ) / 2;
  var yMid = ( yMax + yMin ) / 2;
  var zMid = ( zMax + zMin ) / 2;

  var boxHelper = [ [ [xMin,yMin,zMin],[xMax,yMin,zMin] ],
                    [ [xMin,yMin,zMin],[xMin,yMax,zMin] ],
                    [ [xMin,yMin,zMin],[xMin,yMin,zMax] ],
                    [ [xMax,yMin,zMin],[xMax,yMax,zMin] ],
                    [ [xMax,yMin,zMin],[xMax,yMin,zMax] ],
                    [ [xMin,yMax,zMin],[xMax,yMax,zMin] ],
                    [ [xMin,yMax,zMin],[xMin,yMax,zMax] ],
                    [ [xMin,yMin,zMax],[xMax,yMin,zMax] ],
                    [ [xMin,yMin,zMax],[xMin,yMax,zMax] ],
                    [ [xMax,yMax,zMin],[xMax,yMax,zMax] ],
                    [ [xMax,yMin,zMax],[xMax,yMax,zMax] ],
                    [ [xMin,yMax,zMax],[xMax,yMax,zMax] ] ];

  // default orientation is looking down z-axis, even after displacement
  // need to rotate viewpoint back to origin with composite orientation

  var zRotation = [ Math.PI/2 + Math.atan(yRange/xRange), [ 0, 0, 1 ] ];

  var norm1 = Math.sqrt( xRange**2 + yRange**2 + zRange**2 );
  var norm2 = Math.sqrt( xRange**2 + yRange**2 );

  var xyRotation = [ Math.acos( zRange/norm1 ),
                               [ -yRange/norm2, xRange/norm2, 0 ] ];

  var cr = compositeRotation( zRotation, xyRotation );

  var x3d = `
<X3D width="${width}" height="${height}">
<Scene>
<Background skyColor="1 1 1"></Background>
<Viewpoint position="${xRange+xMid} ${yRange+yMid} ${zRange+zMid}"
           orientation="${cr[1].join(' ')} ${cr[0]}"
           centerOfRotation="${xMid} ${yMid} ${zMid}"></Viewpoint>`;

  if ( frame ) x3d += `
<Shape>
<Appearance><Material emissiveColor='0 0 0'></Material></Appearance>
<LineSet vertexCount='2 2 2 2 2 2 2 2 2 2 2 2'>
<Coordinate point="${boxHelper.map(a => a[0].concat(a[1]).join(' ')).join(',')}"></Coordinate>
</LineSet>
</Shape>`;

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

    var s = surfaces[i];

    // remove faces completely outside vertical range
    for ( var j = s.faces.length - 1 ; j >= 0 ; j-- ) {
      var f = s.faces[j];
      var check = true;
      f.forEach( index => check = check && s.vertices[index][2] < zMin );
      if ( check ) s.faces.splice( j, 1 );
      var check = true;
      f.forEach( index => check = check && s.vertices[index][2] > zMax );
      if ( check ) s.faces.splice( j, 1 );
    }

    // constrain vertices to vertical range
    for ( var j = 0 ; j < s.vertices.length ; j++ ) {
      if ( s.vertices[j][2] < zMin ) s.vertices[j][2] = zMin;
      if ( s.vertices[j][2] > zMax ) s.vertices[j][2] = zMax;
    }

    var indices = '';
    for ( var j = 0 ; j < s.faces.length ; j++ )
      indices += s.faces[j].join(' ') + ' -1 ';

    var points = '';
    for ( var j = 0 ; j < s.vertices.length ; j++ )
      points += s.vertices[j].join(' ') + ' ';

    var p = document.createElement( 'p' );
    p.style.color = s.options.color;
    var rgb = p.style.color.replace( /[^\d,]/g, '' ).split(',');
    rgb.forEach( (e,i,a) => a[i] /= 255 );
    var color = rgb.join(' ');

    x3d += `
<Shape>
<Appearance>
<TwoSidedMaterial diffuseColor="${color}" transparency="${1-s.options.opacity}"></TwoSidedMaterial>
</Appearance>
<IndexedFaceSet creaseAngle="1.57" solid='false' coordIndex="${indices}">
<Coordinate point="${points}"></Coordinate>`;

    if ( 'colors' in s.options ) {
      var colors = '';
      for ( var j = 0 ; j < s.options.colors.length ; j++ ) {
        p.style.color = s.options.colors[j];
        rgb = p.style.color.replace( /[^\d,]/g, '' ).split(',');
        rgb.forEach( (e,i,a) => a[i] /= 255 );
        rgb = roundTo( rgb, 3 );
        colors +=  rgb.join(' ') + ' ';
      }
      x3d += `
<Color color="${colors}"></Color>`;
    }

    x3d += `
</IndexedFaceSet>
</Shape>`;

  }

  x3d += `
</Scene>
</X3D>`;

  if ( config.saveAsXML ) {

    var xml = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "http://www.web3d.org/specifications/x3d-3.3.dtd">
${x3d}`;

    var blob = new Blob( [ xml ] );
    var a = document.body.appendChild( document.createElement( 'a' ) );
    a.href = window.URL.createObjectURL( blob );
    a.download = 'scene.xml';
    a.click();

  }

  var stylesheet = config.viewer === 'x3dom' ?
`<link rel="stylesheet" type="text/css" href="https://www.x3dom.org/download/x3dom.css">` :
`<link rel="stylesheet" type="text/css" href="https://code.create3000.de/x_ite/4.6.9/dist/x_ite.css"/>`;

  var script = config.viewer === 'x3dom' ?
`<script src="https://www.x3dom.org/download/x3dom.js"></script>` :
`

`;
  var html = `

<title></title>
<meta charset="utf-8">
${stylesheet}

${script}

<X3DCanvas style="width: ${width}px; height: ${height}px">
${x3d}
</X3DCanvas>

`;

  var border = config.no3DBorder ? 'none' : '1px solid black';

  return ``;

}

<|endoftext|>


<commit_before>import Plugin from './Plugin'
import tus from 'tus-js-client'

/**
 * Tus resumable file uploader
 *
 */
export default class Tus10 extends Plugin {
  constructor (core, opts) {
    super(core, opts)
    this.type = 'uploader'
    this.id = 'Tus'
    this.title = 'Tus'

    // set default options
    const defaultOptions = {}

    // merge default options with the ones set by user
    this.opts = Object.assign({}, defaultOptions, opts)
  }

/**
 * Create a new Tus upload
 *
 * @param {object} file for use with upload
 * @param {integer} current file in a queue
 * @param {integer} total number of files in a queue
 * @returns {Promise}
 */
  upload (file, current, total) {
    this.core.log(`uploading ${current} of ${total}`)

    // Create a new tus upload
    return new Promise((resolve, reject) => {
      const upload = new tus.Upload(file.data, {

        // TODO merge this.opts or this.opts.tus here
        resume: false,
        endpoint: this.opts.endpoint,
        onError: (error) => {
          reject('Failed because: ' + error)
        },
        onProgress: (bytesUploaded, bytesTotal) => {
          let percentage = (bytesUploaded / bytesTotal * 100).toFixed(2)
          percentage = Math.round(percentage)

          // Dispatch progress event
          this.core.emitter.emit('upload-progress', {
            uploader: this,
            id: file.id,
            percentage: percentage
          })
        },
        onSuccess: () => {
          file.uploadURL = upload.url
          this.core.emitter.emit('upload-success', file)

          this.core.log(`Download ${upload.file.name} from ${upload.url}`)
          resolve(upload)
        }
      })
      upload.start()
    })
  }

  install () {
    this.core.emitter.on('next', () => {
      this.core.log('Tus is uploading..')
      const files = this.core.state.files

      const filesForUpload = {}
      Object.keys(files).forEach((file) => {
        if (files[file].progress === 0 || files[file].remote) {
          filesForUpload[file] = files[file]
        }
      })

      this.uploadFiles(filesForUpload)
    })
  }

  uploadFiles (files) {
    const uploaders = []
    for (let i in files) {
      const file = files[i]
      const current = parseInt(i, 10) + 1
      const total = files.length

      if (!files[i].remote) {
        uploaders.push(this.upload(file, current, total))
      } else {
        uploaders.push(this.uploadRemote(file, current, total))
      }
    }

    return Promise.all(uploaders).then(() => {
      return {
        uploadedCount: files.length
      }
    })
  }

  uploadRemote (file, current, total) {
    return new Promise((resolve, reject) => {
      fetch(file.remote.url, {
        method: 'get',
        credentials: 'include',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        }
      })
      .then((res) => {
        console.log(res)
      })
    })
  }

/**
 * Add files to an array of `upload()` calles, passing the current and total file count numbers
 *
 * @param {Array | Object} results
 * @returns {Promise} of parallel uploads `Promise.all(uploaders)`
 */
  run (results) {
    this.core.log({
      class: this.constructor.name,
      method: 'run',
      results: results
    })

    return this.uploadFiles(results)
  }
}
<commit_msg>Remote file error handling<commit_after>import Plugin from './Plugin'
import tus from 'tus-js-client'

/**
 * Tus resumable file uploader
 *
 */
export default class Tus10 extends Plugin {
  constructor (core, opts) {
    super(core, opts)
    this.type = 'uploader'
    this.id = 'Tus'
    this.title = 'Tus'

    // set default options
    const defaultOptions = {}

    // merge default options with the ones set by user
    this.opts = Object.assign({}, defaultOptions, opts)
  }

/**
 * Create a new Tus upload
 *
 * @param {object} file for use with upload
 * @param {integer} current file in a queue
 * @param {integer} total number of files in a queue
 * @returns {Promise}
 */
  upload (file, current, total) {
    this.core.log(`uploading ${current} of ${total}`)

    // Create a new tus upload
    return new Promise((resolve, reject) => {
      const upload = new tus.Upload(file.data, {

        // TODO merge this.opts or this.opts.tus here
        resume: false,
        endpoint: this.opts.endpoint,
        onError: (error) => {
          reject('Failed because: ' + error)
        },
        onProgress: (bytesUploaded, bytesTotal) => {
          let percentage = (bytesUploaded / bytesTotal * 100).toFixed(2)
          percentage = Math.round(percentage)

          // Dispatch progress event
          this.core.emitter.emit('upload-progress', {
            uploader: this,
            id: file.id,
            percentage: percentage
          })
        },
        onSuccess: () => {
          file.uploadURL = upload.url
          this.core.emitter.emit('upload-success', file)

          this.core.log(`Download ${upload.file.name} from ${upload.url}`)
          resolve(upload)
        }
      })
      upload.start()
    })
  }

  install () {
    this.core.emitter.on('next', () => {
      this.core.log('Tus is uploading..')
      const files = this.core.state.files

      const filesForUpload = {}
      Object.keys(files).forEach((file) => {
        if (files[file].progress === 0 || files[file].remote) {
          filesForUpload[file] = files[file]
        }
      })

      this.uploadFiles(filesForUpload)
    })
  }

  uploadFiles (files) {
    const uploaders = []
    for (let i in files) {
      const file = files[i]
      const current = parseInt(i, 10) + 1
      const total = files.length

      if (!files[i].remote) {
        uploaders.push(this.upload(file, current, total))
      } else {
        uploaders.push(this.uploadRemote(file, current, total))
      }
    }

    return Promise.all(uploaders).then(() => {
      return {
        uploadedCount: files.length
      }
    })
  }

  uploadRemote (file, current, total) {
    return new Promise((resolve, reject) => {
      fetch(file.remote.url, {
        method: 'get',
        credentials: 'include',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        }
      })
      .then((res) => {
        if (res.status >= 200 && res.status <= 300) {
          this.core.log(`Remote upload of '${file.name}' successful`)
          return resolve('Success')
        }
        this.core.log(`Remote upload of file '${file.name}' failed`)
        return reject(new Error('Error: ' + res.statusText))
      })
    })
  }

/**
 * Add files to an array of `upload()` calles, passing the current and total file count numbers
 *
 * @param {Array | Object} results
 * @returns {Promise} of parallel uploads `Promise.all(uploaders)`
 */
  run (results) {
    this.core.log({
      class: this.constructor.name,
      method: 'run',
      results: results
    })

    return this.uploadFiles(results)
  }
}
<|endoftext|>


<commit_before>// install  :     cordova plugin add https://github.com/katzer/cordova-plugin-badge.git
// link     :     https://github.com/katzer/cordova-plugin-badge

angular.module('ngCordova.plugins.badge', [])

  .factory('$cordovaBadge', ['$q', function ($q) {

    return {
      hasPermission: function () {
        var q = $q.defer();
        cordova.plugins.notification.badge.hasPermission(function (permission) {
          if (permission) {
            q.resolve(true);
          } else {
            q.reject("You do not have permission");
          }
        });

        return q.promise;
      },

      promptForPermission: function () {
        return cordova.plugins.notification.badge.promptForPermission();
      },

      set: function (number) {
        var q = $q.defer();

        cordova.plugins.notification.badge.hasPermission(function (permission) {
          if (permission) {
            q.resolve(cordova.plugins.notification.badge.set(number));
          } else {
            q.reject("You do not have permission to set Badge");
          }
        });
        return q.promise;
      },

      get: function () {
        var q = $q.defer();
        cordova.plugins.notification.badge.hasPermission(function (permission) {
          if (permission) {
            cordova.plugins.notification.badge.get(function (badge) {
              q.resolve(badge);
            });
          } else {
            q.reject("You do not have permission to get Badge");
          }
        });

        return q.promise;
      },

      clear: function () {
        var q = $q.defer();

        cordova.plugins.notification.badge.hasPermission(function (permission) {
          if (permission) {
            q.resolve(cordova.plugins.notification.badge.clear());
          } else {
            q.reject("You do not have permission to clear Badge");
          }
        });
        return q.promise;
      },

      configure: function (config) {
        return cordova.plugins.notification.badge.configure(config);
      }
    };
  }]);
<commit_msg>added increase and decrease functions and cleaned up a little<commit_after>// install  :     cordova plugin add https://github.com/katzer/cordova-plugin-badge.git
// link     :     https://github.com/katzer/cordova-plugin-badge

angular.module('ngCordova.plugins.badge', [])

  .factory('$cordovaBadge', ['$q', function ($q) {

    return {
      hasPermission: function () {
        var q = $q.defer();
        cordova.plugins.notification.badge.hasPermission(function (permission) {
          if (permission) {
            q.resolve(true);
          } else {
            q.reject('You do not have permission');
          }
        });

        return q.promise;
      },

      promptForPermission: function () {
        return cordova.plugins.notification.badge.promptForPermission();
      },

      set: function (badge, callback, scope) {
        var q = $q.defer();

        cordova.plugins.notification.badge.hasPermission(function (permission) {
          if (permission) {
            q.resolve(
              cordova.plugins.notification.badge.set(badge, callback, scope)
            );
          } else {
            q.reject('You do not have permission to set Badge');
          }
        });
        return q.promise;
      },

      get: function () {
        var q = $q.defer();
        cordova.plugins.notification.badge.hasPermission(function (permission) {
          if (permission) {
            cordova.plugins.notification.badge.get(function (badge) {
              q.resolve(badge);
            });
          } else {
            q.reject('You do not have permission to get Badge');
          }
        });

        return q.promise;
      },

      clear: function (callback, scope) {
        var q = $q.defer();

        cordova.plugins.notification.badge.hasPermission(function (permission) {
          if (permission) {
            q.resolve(cordova.plugins.notification.badge.clear(callback, scope));
          } else {
            q.reject('You do not have permission to clear Badge');
          }
        });
        return q.promise;
      },

      increase: function (count, callback, scope) {
        var q = $q.defer();

        this.hasPermission().then(function (){
          q.resolve(
            cordova.plugins.notification.badge.increase(count, callback, scope)
          );
        }, function (){
          q.reject('You do not have permission to increase Badge');
        }) ;

        return q.promise;
      },

      decrease: function (count, callback, scope) {
        var q = $q.defer();

        this.hasPermission().then(function (){
          q.resolve(
            cordova.plugins.notification.badge.decrease(count, callback, scope)
          );
        }, function (){
          q.reject('You do not have permission to decrease Badge');
        }) ;

        return q.promise;
      },

      configure: function (config) {
        return cordova.plugins.notification.badge.configure(config);
      }
    };
  }]);
<|endoftext|>


<commit_before>import Bulma from '../core';

/**
 * @module Modal
 * @since  0.1.0
 * @author  Thomas Erbe <vizuaalog@gmail.com>
 */
class Modal {
    /**
     * Plugin constructor
     * @param  {Object} options The options object for this plugin
     * @return {this} The newly created plugin instance
     */
    constructor(options) {
        if(!options) {
            options = {};
        }

        /**
         * Message body text.
         * @type {string}
         */
        this.root = options.hasOwnProperty('element') ? options.element : '';

        /**
         * Closable toggle switch.
         * @type {bool}
         */
        this.closable = options.hasOwnProperty('closable') ? options.closable : true ;

        /**
         * The element used to close the message.
         * @type {HTMLElement}
         */
        this.closeButton = this.findCloseButton();

        /**
         * Create a bound version of our close event handler, this will
         * allow us to remove the event listener later on.
         *
         * @type {Function}
         */
        this.boundHandleCloseEvent = this.handleCloseEvent.bind(this);

        if(this.closeButton && this.closable ) {
            this.setupCloseEvent();
        }

        /**
         * Create a bound version of our event escape event handler, this will
         * allow us to remove the event listener later on.
         *
         * @type {Function}
         */
        this.boundHandleEscapeClose = this.handleEscapeClose.bind(this);

        document.addEventListener('keyup', this.boundHandleEscapeClose);
    }

    /**
     * Helper method used by the Bulma core to create a new instance.
     * @param  {Object} options THe options object for the new instance
     * @return {Modal} The newly created instance
     */
    static create(options) {
        return new Modal(options);
    }

    /**
     * Show the message.
     * @return {undefined}
     */
    open() {
        this.root.classList.add('is-active');
    }

    /**
     * Hide the message.
     * @return {undefined}
     */
    close() {
        this.root.classList.remove('is-active');
    }

    /**
     * Find the close button.
     * @return {HTMLElement} The newly created element
     */
    findCloseButton() {
        let element = this.root.querySelector('.modal-close');

        if(!element) {
            return this.root.querySelector('.delete');
        }

        return element;
    }

    /**
     * Setup the event listener for the close button.
     * @return {undefined}
     */
    setupCloseEvent() {
        this.closeButton.addEventListener('click', this.boundHandleCloseEvent);
    }

    /**
     * Handle the event when our close button is clicked.
     * @return {undefined}
     */
    handleCloseEvent() {
        this.close();
    }

    /**
     * Close the modal if the Escape key is pressed
     * @return {undefined}
     */
    handleEscapeClose(event) {
        let key = event.key || event.keyCode;

        if(key === 'Escape' || key === 'Esc' || key === 27) {
            this.close();
        }
    }

    /**
     * Destroy the message, removing the event listener, interval and element.
     * @return {undefined}
     */
    destroy() {
        if(this.closable && this.closeButton) {
            this.closeButton.removeEventListener('click', this.boundHandleCloseEvent);
        }

        document.removeEventListener('keyup', this.boundHandleEscapeClose);

        this.root = null;
        this.closeButton = null;
    }

    /**
     * Handle parsing the DOMs data attribute API.
     * @return {undefined}
     */
    static handleDomParsing() {
        return;
    }

    static getRootClass() {
        return 'modal';
    }
}

Bulma.registerPlugin('modal', Modal);

export default Modal;
<commit_msg>Close the modal when clicking outside. #27<commit_after>import Bulma from '../core';

/**
 * @module Modal
 * @since  0.1.0
 * @author  Thomas Erbe <vizuaalog@gmail.com>
 */
class Modal {
    /**
     * Plugin constructor
     * @param  {Object} options The options object for this plugin
     * @return {this} The newly created plugin instance
     */
    constructor(options) {
        if(!options) {
            options = {};
        }

        /**
         * Message body text.
         * @type {string}
         */
        this.root = options.hasOwnProperty('element') ? options.element : '';

        /**
         * Closable toggle switch.
         * @type {bool}
         */
        this.closable = options.hasOwnProperty('closable') ? options.closable : true ;

        /**
         * The element used to close the message.
         * @type {HTMLElement}
         */
        this.closeButton = this.findCloseButton();

        /**
         * Create a bound version of our close event handler, this will
         * allow us to remove the event listener later on.
         *
         * @type {Function}
         */
        this.boundHandleCloseEvent = this.handleCloseEvent.bind(this);

        if(this.closeButton && this.closable ) {
            this.setupCloseEvent();
        }

        this.modalBackground = this.root.querySelector('.modal-background');
        this.modalBackground.addEventListener('click', this.boundHandleCloseEvent);

        /**
         * Create a bound version of our event escape event handler, this will
         * allow us to remove the event listener later on.
         *
         * @type {Function}
         */
        this.boundHandleEscapeClose = this.handleEscapeClose.bind(this);

        document.addEventListener('keyup', this.boundHandleEscapeClose);
    }

    /**
     * Helper method used by the Bulma core to create a new instance.
     * @param  {Object} options THe options object for the new instance
     * @return {Modal} The newly created instance
     */
    static create(options) {
        return new Modal(options);
    }

    /**
     * Show the message.
     * @return {undefined}
     */
    open() {
        this.root.classList.add('is-active');
    }

    /**
     * Hide the message.
     * @return {undefined}
     */
    close() {
        this.root.classList.remove('is-active');
    }

    /**
     * Find the close button.
     * @return {HTMLElement} The newly created element
     */
    findCloseButton() {
        let element = this.root.querySelector('.modal-close');

        if(!element) {
            return this.root.querySelector('.delete');
        }

        return element;
    }

    /**
     * Setup the event listener for the close button.
     * @return {undefined}
     */
    setupCloseEvent() {
        this.closeButton.addEventListener('click', this.boundHandleCloseEvent);
    }

    /**
     * Handle the event when our close button is clicked.
     * @return {undefined}
     */
    handleCloseEvent() {
        this.close();
    }

    /**
     * Close the modal if the Escape key is pressed
     * @return {undefined}
     */
    handleEscapeClose(event) {
        let key = event.key || event.keyCode;

        if(key === 'Escape' || key === 'Esc' || key === 27) {
            this.close();
        }
    }

    /**
     * Destroy the message, removing the event listener, interval and element.
     * @return {undefined}
     */
    destroy() {
        if(this.closable && this.closeButton) {
            this.closeButton.removeEventListener('click', this.boundHandleCloseEvent);
        }

        document.removeEventListener('keyup', this.boundHandleEscapeClose);
        this.modalBackground.removeEventListener('click', this.boundHandleCloseEvent);

        this.root = null;
        this.closeButton = null;
    }

    /**
     * Handle parsing the DOMs data attribute API.
     * @return {undefined}
     */
    static handleDomParsing() {
        return;
    }

    static getRootClass() {
        return 'modal';
    }
}

Bulma.registerPlugin('modal', Modal);

export default Modal;
<|endoftext|>