<commit_before>'use strict';

var Code = require('code'); // the assertions library
var Lab = require('lab'); // the test framework
var Config = require('../../lib/config');
var Monitor = require('../../lib/plugins/monitor');

var lab = exports.lab = Lab.script(); // export the test script

// make lab feel like jasmine
var describe = lab.experiment;
var it = lab.test;
var expect = Code.expect;

var internals = {};
internals.manifest = {
    connections: [{
        port: 0
    }],
    registrations: [{
        plugin: './plugins/monitor'
    }]
};

describe('Plugin: monitor', function() {

    it('handle good plugin registration failure', function(done) {

        var PLUGIN_ERROR = 'plugin error';
        var fakeServer = {};
        fakeServer.on = function() {};

        fakeServer.register = function(plugin, next) {
            return next(new Error(PLUGIN_ERROR));
        };

        Monitor.register(fakeServer, null, function(error) {

            expect(error).to.exist();
            expect(error.message).to.equals(PLUGIN_ERROR);
            done();
        });
    });

    it('subscribes to route events', function(done) {

        var routeData = {
            realm: {
                plugin: 'test'
            },
            method: 'get',
            path: '/'
        };

        var fakeServer = {};
        fakeServer.on = function(event, next) {
            expect(event).to.match(/(route|request)/);
            expect(next).to.be.a.function();
            if(event === 'route') {
                next(routeData);
            }
        };

        fakeServer.log = function(tags, data) {
            expect(tags).to.be.an.array();
            expect(tags.indexOf('route')).not.to.equal(-1);
            expect(data.plugin).to.equals(routeData.realm.plugin);
            expect(data.method).to.equals(routeData.method);
            expect(data.path).to.equals(routeData.path);
        };

        fakeServer.register = function(plugin, next) {
            return next();
        };

        Monitor.register(fakeServer, null, function(error) {

            expect(error).to.not.exist();
            done();
        });
    });

    it('subscribes to request events', function(done) {

        var REQ_ID = 'XPTO';

        var requestData = {
            url: {
                path: '/'
            },
            info: {
                remoteAddress: '127.0.0.1'
            },
            headers: {}
        };
        requestData.headers['x-forwarded-for'] = requestData.info.remoteAddress;

        var eventData = {
            tags: ['someTag'],
            request: 'xxx:yyy:zzz:' + REQ_ID
        };

        var fakeServer = {};
        fakeServer.on = function(event, next) {
            expect(event).to.match(/(route|request)/);
            expect(next).to.be.a.function();
            if(event === 'request') {
                next(requestData, eventData);
            }
        };

        fakeServer.log = function(tags, data) {
            expect(tags).to.equals(eventData.tags);
            expect(data.id).to.equals(REQ_ID);
            expect(data.path).to.equals(requestData.url.path);
            expect(data.address).to.equals(requestData.info.remoteAddress);
        };

        fakeServer.register = function(plugin, next) {
            return next();
        };

        Monitor.register(fakeServer, null, function(error) {

            expect(error).to.not.exist();
            done();
        });
    });

    it('registers server log events to console reporter', {
        parallel: false // required as Config plugin is changed during execution
    }, function(done) {

        var origDebug = Config.monitor.debug;
        Config.monitor.debug = false;

        var fakeServer = {};
        fakeServer.on = function() {};
        fakeServer.register = function(plugin, next) {
            expect(plugin).to.exist();
            expect(plugin.options).to.be.an.object();
            expect(plugin.options.reporters).to.be.an.object();
            expect(plugin.options.reporters.console).to.be.an.array();
            expect(plugin.options.reporters.console[0].args).to.be.an.array();
            expect(plugin.options.reporters.console[0].args[0].response).to.not.exist();
            expect(plugin.options.reporters.console[0].args[0].route).to.not.exist();
            return next();
        };

        Monitor.register(fakeServer, null, function(error) {

            expect(error).to.not.exist();
            Config.monitor.debug = origDebug;
            done();
        });

    });

    it('registers route and response events to console reporter in debug', {
        parallel: false // required as Config plugin is changed during execution
    }, function(done) {

        var origDebug = Config.monitor.debug;
        Config.monitor.debug = true;

        var fakeServer = {};
        fakeServer.on = function() {};
        fakeServer.register = function(plugin, next) {
            expect(plugin).to.exist();
            expect(plugin.options).to.be.an.object();
            expect(plugin.options.reporters).to.be.an.object();
            expect(plugin.options.reporters.console).to.be.an.array();
            expect(plugin.options.reporters.console[0].args).to.be.an.array();
            expect(plugin.options.reporters.console[0].args[0].response).to.exist();
            expect(plugin.options.reporters.console[0].args[0].route).to.exist();
            return next();
        };

        Monitor.register(fakeServer, null, function(error) {

            expect(error).to.not.exist();
            Config.monitor.debug = origDebug;
            done();
        });

    });

});
<commit_msg>improved test coverage<commit_after>'use strict';

var Code = require('code'); // the assertions library
var Lab = require('lab'); // the test framework
var Path = require('path');
var Config = require('../../lib/config');
var Monitor = require('../../lib/plugins/monitor');
var Server = require('../../lib/server');

var lab = exports.lab = Lab.script(); // export the test script

// make lab feel like jasmine
var describe = lab.experiment;
var it = lab.test;
var expect = Code.expect;

var internals = {};
internals.manifest = {
    connections: [{
        port: 0
    }],
    registrations: [{
        plugin: './plugins/monitor'
    }]
};

internals.composeOptions = {
    relativeTo: Path.resolve(__dirname, '../../lib'),
};

describe('Plugin: monitor', function() {

    it('handle good plugin registration failure', function(done) {

        var PLUGIN_ERROR = 'plugin error';
        var fakeServer = {};
        fakeServer.on = function() {};

        fakeServer.register = function(plugin, next) {
            return next(new Error(PLUGIN_ERROR));
        };

        Monitor.register(fakeServer, null, function(error) {

            expect(error).to.exist();
            expect(error.message).to.equals(PLUGIN_ERROR);
            done();
        });
    });

    it('handles request events with debug disabled', function(done) {

        var orig = Config.monitor.debug;
        Config.monitor.debug = false;

        var eventData = {
            tags: ['someTag'],
            data: {
                info: {}
            }
        };

        var fakeServer = {};
        fakeServer.on = function(event, next) {
            expect(event).to.match(/(route|request)/);
            expect(next).to.be.a.function();
            if (event === 'request') {
                next({}, eventData);
            }
        };

        fakeServer.log = function(tags, data) {
            expect(tags).to.equals(eventData.tags);
            expect(data.info).to.exist();
        };

        fakeServer.register = function(plugin, next) {
            return next();
        };

        Monitor.register(fakeServer, null, function(error) {

            expect(error).to.not.exist();
            Config.monitor.debug = orig;
            done();
        });
    });

    it('handles request events', function(done) {

        var orig = Config.monitor.debug;
        Config.monitor.debug = true;

        var REQ_ID = 'XPTO';

        var requestData = {
            url: {
                path: '/'
            },
            info: {
                remoteAddress: '127.0.0.1'
            },
            headers: {}
        };
        requestData.headers['x-forwarded-for'] = requestData.info.remoteAddress;

        var eventData = {
            tags: ['someTag'],
            request: 'xxx:yyy:zzz:' + REQ_ID,
            data: {
                info: {}
            }
        };

        var fakeServer = {};
        fakeServer.on = function(event, next) {
            expect(event).to.match(/(route|request)/);
            expect(next).to.be.a.function();
            if (event === 'request') {
                next(requestData, eventData);
            }
        };

        fakeServer.log = function(tags, data) {
            expect(tags).to.equals(eventData.tags);
            expect(data.id).to.equals(REQ_ID);
            expect(data.path).to.equals(requestData.url.path);
            expect(data.address).to.equals(requestData.info.remoteAddress);
            expect(data.info).to.exist();
        };

        fakeServer.register = function(plugin, next) {
            return next();
        };

        Monitor.register(fakeServer, null, function(error) {

            expect(error).to.not.exist();
            Config.monitor.debug = orig;
            done();
        });
    });

    it('logs route events', {
        parallel: false
    }, function(done) {

        var orig = Config.monitor.debug;
        Config.monitor.debug = false; // prevents debug logging during tests

        Server.init(internals.manifest, internals.composeOptions, function(err, server) {

            var route = {
                method: 'get',
                path: '/',
                handler: function() {}
            };

            server.once('log', function(event, tags) {
                expect(tags.server).to.be.true();
                expect(tags.route).to.be.true();
                expect(tags.debug).to.be.true();
                expect(event.data.plugin).to.exist();
                expect(event.data.method).to.equal(route.method);
                expect(event.data.path).to.equal(route.path);
                Config.monitor.debug = orig;
                server.stop(done);
            });

            server.route(route);

        });
    });

    it('logs request events', {
        parallel: false
    }, function(done) {

        var orig = Config.monitor.debug;
        Config.monitor.debug = false; // prevents debug logging during tests

        Server.init(internals.manifest, internals.composeOptions, function(err, server) {

            var requestData = {
                user: 'test'
            };

            var route = {
                method: 'get',
                path: '/',
                handler: function(request) {
                    request.log(['debug', 'someTag'], requestData);
                }
            };

            server.once('request', function(serverObj, event, tags) {
                expect(event.data).to.equals(requestData);
                expect(tags).to.include(['debug', 'someTag']);
                Config.monitor.debug = orig;
                server.stop(done);
            });

            server.route(route);
            server.inject('/', function() {});

        });
    });

    it('logs request events with no data', {
        parallel: false
    }, function(done) {

        var orig = Config.monitor.debug;
        Config.monitor.debug = false; // prevents debug logging during tests

        Server.init(internals.manifest, internals.composeOptions, function(err, server) {

            var route = {
                method: 'get',
                path: '/',
                handler: function(request) {
                    request.log(['debug', 'someTag']);
                }
            };

            server.once('request', function(serverObj, event, tags) {
                expect(tags).to.include(['debug', 'someTag']);
                Config.monitor.debug = orig;
                server.stop(done);
            });

            server.route(route);
            server.inject('/', function() {});

        });
    });

    it('registers server log events to console reporter', {
        parallel: false // required as Config plugin is changed during execution
    }, function(done) {

        var origDebug = Config.monitor.debug;
        Config.monitor.debug = false;

        var fakeServer = {};
        fakeServer.on = function() {};
        fakeServer.register = function(plugin, next) {
            expect(plugin).to.exist();
            expect(plugin.options).to.be.an.object();
            expect(plugin.options.reporters).to.be.an.object();
            expect(plugin.options.reporters.console).to.be.an.array();
            expect(plugin.options.reporters.console[0].args).to.be.an.array();
            expect(plugin.options.reporters.console[0].args[0].response).to.not.exist();
            expect(plugin.options.reporters.console[0].args[0].route).to.not.exist();
            return next();
        };

        Monitor.register(fakeServer, null, function(error) {

            expect(error).to.not.exist();
            Config.monitor.debug = origDebug;
            done();
        });

    });

    it('registers route and response events to console reporter in debug', {
        parallel: false // required as Config plugin is changed during execution
    }, function(done) {

        var origDebug = Config.monitor.debug;
        Config.monitor.debug = true;

        var fakeServer = {};
        fakeServer.on = function() {};
        fakeServer.register = function(plugin, next) {
            expect(plugin).to.exist();
            expect(plugin.options).to.be.an.object();
            expect(plugin.options.reporters).to.be.an.object();
            expect(plugin.options.reporters.console).to.be.an.array();
            expect(plugin.options.reporters.console[0].args).to.be.an.array();
            expect(plugin.options.reporters.console[0].args[0].response).to.exist();
            expect(plugin.options.reporters.console[0].args[0].route).to.exist();
            return next();
        };

        Monitor.register(fakeServer, null, function(error) {

            expect(error).to.not.exist();
            Config.monitor.debug = origDebug;
            done();
        });

    });

});
<|endoftext|>


<commit_before>'use strict';

exports.config = {
    allScriptsTimeout: 11000,

    specs: [
        'e2e/*.js'
    ],

    capabilities: {
        'browserName': 'firefox'
    },

    baseUrl: 'http://localhost:8000/app/',

    framework: 'jasmine',

    jasmineNodeOpts: {
        defaultTimeoutInterval: 30000
    }
};
<commit_msg>protractor: resize browser window to 640x480 on startup<commit_after>'use strict';

exports.config = {
    allScriptsTimeout: 11000,

    specs: [
        'e2e/*.js'
    ],

    capabilities: {
        'browserName': 'firefox'
    },

    baseUrl: 'http://localhost:8000/app/',

    onPrepare: function () {
        var width = 640;
        var height = 480;
        browser.driver.manage().window().setSize(width, height);
    },

    framework: 'jasmine',

    jasmineNodeOpts: {
        defaultTimeoutInterval: 30000
    }
};
<|endoftext|>


<commit_before>import chai from 'chai';
import hamt from 'hamt';
import From, {Constants} from '../src/index.js';

const expect = chai.expect;

describe('Reducer queries', () => {

  // Query reducing...

  it('should reduce the query From.value(10) to 10', () => {
    // Arrange
    const query = From.value(10);
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce();
    // Assert
    expect(newState).to.equal(10);
  });

  it('should reduce the query From.value(10).select(x => x * 2) to 20', () => {
    // Arrange
    const query = From.value(10).select(x => x * 2);
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce();
    // Assert
    expect(newState).to.equal(20);
  });

  it('should reduce the query From.value(10).where(x => x === 10) to 10', () => {
    // Arrange
    const query = From.value(10).where(x => x === 10);
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce();
    // Assert
    expect(newState).to.equal(10);
  });

  it('should reduce the query From.value(10).where(x => x === 20) to undefined', () => {
    // Arrange
    const query = From.value(10).where(x => x === 20);
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce();
    // Assert
    expect(newState).to.not.exist;
  });

  it('should reduce the query From.events().ofType("abc") and events { type: "abc" } to { type: "abc" }', () => {
    // Arrange
    const query = From.events().ofType('abc');
    const event = { type: 'abc' };
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce({event});
    // Assert
    expect(newState).to.deep.equal(event);
  });

  it('should reduce the query From.events().ofType("abc") and events { type: "def" } to undefined', () => {
    // Arrange
    const query = From.events().ofType('abc');
    const event = { type: 'def' };
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce({event});
    // Assert
    expect(newState).to.not.exist;
  });

  it('should reduce the query From.events().ofAnyType() and events { type: "abc" } to { type: "abc" }', () => {
    // Arrange
    const query = From.events().ofAnyType();
    const event = { type: 'abc' };
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce({event});
    // Assert
    expect(newState).to.deep.equal(event);
  });

  it('should reduce constant structures to themselves', () => {
    // Arrange
    const structure = { foo: 'abc', bar: 'def' };
    const query = From.structure(structure);
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce();
    // Assert
    expect(newState).to.deep.equal(structure);
  });

  it('should reduce reduced properties as part of a structure query', () => {
    // Arrange
    const structure = {
      foo: 'abc',
      bar: From.value(10),
      baz: From.events().ofType('test-event-type').select(e => e.value)
    };
    const query = From.structure(structure);
    // Act
    const reducer = query.build();
    const event = { type: 'test-event-type', value: 42 };
    const {newState} = reducer.reduce({event});
    // Assert
    expect(newState).to.deep.equal({
      foo: 'abc',
      bar: 10,
      baz: 42
    });
  });

  it('should reduce the query From.events().ofType("inc").select(_ => 1).sum(0) and 3 events { type: "inc"} to 3', () => {
    const query = From.events().ofType('inc').select(_ => 1).sum(0);
    const event = { type: 'inc' };
    // Act
    const reducer = query.build();
    let state, aux;
    for (var i = 0; i < 3; i++) {
      const {newState, newAuxillary} = reducer.reduce({previousState: state, previousAuxillary: aux, event});
      state = newState;
      aux = newAuxillary;
    }
    // Assert
    expect(state).to.equal(3);
  });

  it('should reduce queries containing projections after reductions', () => {
    const query = From.events().ofType('inc').select(_ => 1).sum(0).select(x => 2 * x);
    const event = { type: 'inc' };
    // Act
    const reducer = query.build();
    let state, aux;
    for (var i = 0; i < 3; i++) {
      const {newState, newAuxillary} = reducer.reduce({previousState: state, previousAuxillary: aux, event});
      state = newState;
      aux = newAuxillary;
    }
    // Assert
    expect(state).to.equal(6);
  });

  it('should reduce to seed values before a matching event occurs', () => {
    const query = From.events().ofAnyType().where(_ => false).sum(10);
    const event = { type: 'inc' };
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce({event});
    // Assert
    expect(newState).to.equal(10);
  });

  // Handled events....

  it('should have no handled events for query From.value(10)', () => {
    // Arrange
    const query = From.value(10);
    // Act
    const reducer = query.build();
    // Assert
    expect(hamt.count(reducer.handledEventTypes)).to.equal(0);
  });

  it('should handle "abc" events for query From.events().ofType("abc")', () => {
    // Arrange
    const query = From.events().ofType('abc');
    // Act
    const reducer = query.build();
    // Assert
    expect(hamt.pairs(reducer.handledEventTypes)).to.deep.equal([
      ['abc', true]
    ]);
  });

  it('should handle "*" handled events for query From.events().ofAnyType()', () => {
    // Arrange
    const query = From.events().ofAnyType();
    // Act
    const reducer = query.build();
    // Assert
    expect(hamt.pairs(reducer.handledEventTypes)).to.deep.equal([
      [Constants.ALL_EVENT_TYPES, true]
    ]);
  });

  it('should have no handled events for constant structures', () => {
    // Arrange
    const structure = { foo: 'abc', bar: 'def' };
    const query = From.structure(structure);
    // Act
    const reducer = query.build();
    // Assert
    expect(hamt.count(reducer.handledEventTypes)).to.equal(0);
  });

  it('should handle the union of events handled by reducer properties in structure queries', () => {
    // Arrange
    const structure = {
      foo: 'abc',
      bar: From.value(10),
      baz: From.events().ofType('event-type-a').select(e => e.value),
      woo: From.events().ofType('event-type-b')
    };
    const query = From.structure(structure);
    // Act
    const reducer = query.build();
    // Assert
    expect(hamt.pairs(reducer.handledEventTypes)).to.deep.equal([
      ['event-type-a', true],
      ['event-type-b', true]
    ]);
  });

  it('should handle "abc" events for query From.events().ofType("abc").select(_ => 1).sum(0)', () => {
    // Arrange
    const query = From.events().ofType('abc').select(_ => 1).sum(0);
    // Act
    const reducer = query.build();
    // Assert
    expect(hamt.pairs(reducer.handledEventTypes)).to.deep.equal([
      ['abc', true]
    ]);
  });

});<commit_msg>Temporarily disabling tests that aren't implemented.<commit_after>import chai from 'chai';
import hamt from 'hamt';
import From, {Constants} from '../src/index.js';

const expect = chai.expect;

describe('Reducer queries', () => {

  // Query reducing...

  it('should reduce the query From.value(10) to 10', () => {
    // Arrange
    const query = From.value(10);
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce();
    // Assert
    expect(newState).to.equal(10);
  });

  it('should reduce the query From.value(10).select(x => x * 2) to 20', () => {
    // Arrange
    const query = From.value(10).select(x => x * 2);
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce();
    // Assert
    expect(newState).to.equal(20);
  });

  it('should reduce the query From.value(10).where(x => x === 10) to 10', () => {
    // Arrange
    const query = From.value(10).where(x => x === 10);
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce();
    // Assert
    expect(newState).to.equal(10);
  });

  it('should reduce the query From.value(10).where(x => x === 20) to undefined', () => {
    // Arrange
    const query = From.value(10).where(x => x === 20);
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce();
    // Assert
    expect(newState).to.not.exist;
  });

  it('should reduce the query From.events().ofType("abc") and events { type: "abc" } to { type: "abc" }', () => {
    // Arrange
    const query = From.events().ofType('abc');
    const event = { type: 'abc' };
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce({event});
    // Assert
    expect(newState).to.deep.equal(event);
  });

  it('should reduce the query From.events().ofType("abc") and events { type: "def" } to undefined', () => {
    // Arrange
    const query = From.events().ofType('abc');
    const event = { type: 'def' };
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce({event});
    // Assert
    expect(newState).to.not.exist;
  });

  it('should reduce the query From.events().ofAnyType() and events { type: "abc" } to { type: "abc" }', () => {
    // Arrange
    const query = From.events().ofAnyType();
    const event = { type: 'abc' };
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce({event});
    // Assert
    expect(newState).to.deep.equal(event);
  });

  it('should reduce constant structures to themselves', () => {
    // Arrange
    const structure = { foo: 'abc', bar: 'def' };
    const query = From.structure(structure);
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce();
    // Assert
    expect(newState).to.deep.equal(structure);
  });

  it('should reduce reduced properties as part of a structure query', () => {
    // Arrange
    const structure = {
      foo: 'abc',
      bar: From.value(10),
      baz: From.events().ofType('test-event-type').select(e => e.value)
    };
    const query = From.structure(structure);
    // Act
    const reducer = query.build();
    const event = { type: 'test-event-type', value: 42 };
    const {newState} = reducer.reduce({event});
    // Assert
    expect(newState).to.deep.equal({
      foo: 'abc',
      bar: 10,
      baz: 42
    });
  });

  it('should reduce the query From.events().ofType("inc").select(_ => 1).sum(0) and 3 events { type: "inc"} to 3', () => {
    const query = From.events().ofType('inc').select(_ => 1).sum(0);
    const event = { type: 'inc' };
    // Act
    const reducer = query.build();
    let state, aux;
    for (var i = 0; i < 3; i++) {
      const {newState, newAuxillary} = reducer.reduce({previousState: state, previousAuxillary: aux, event});
      state = newState;
      aux = newAuxillary;
    }
    // Assert
    expect(state).to.equal(3);
  });

  it('should reduce queries containing projections after reductions', () => {
    const query = From.events().ofType('inc').select(_ => 1).sum(0).select(x => 2 * x);
    const event = { type: 'inc' };
    // Act
    const reducer = query.build();
    let state, aux;
    for (var i = 0; i < 3; i++) {
      const {newState, newAuxillary} = reducer.reduce({previousState: state, previousAuxillary: aux, event});
      state = newState;
      aux = newAuxillary;
    }
    // Assert
    expect(state).to.equal(6);
  });

  it('should reduce to seed values before a matching event occurs', () => {
    const query = From.events().ofAnyType().where(_ => false).sum(10);
    const event = { type: 'inc' };
    // Act
    const reducer = query.build();
    const {newState} = reducer.reduce({event});
    // Assert
    expect(newState).to.equal(10);
  });

  // Handled events....
  /* TODO: This should probably be tested somewhere else...
  it('should have no handled events for query From.value(10)', () => {
    // Arrange
    const query = From.value(10);
    // Act
    const reducer = query.build();
    // Assert
    expect(hamt.count(reducer.handledEventTypes)).to.equal(0);
  });

  it('should handle "abc" events for query From.events().ofType("abc")', () => {
    // Arrange
    const query = From.events().ofType('abc');
    // Act
    const reducer = query.build();
    // Assert
    expect(hamt.pairs(reducer.handledEventTypes)).to.deep.equal([
      ['abc', true]
    ]);
  });

  it('should handle "*" handled events for query From.events().ofAnyType()', () => {
    // Arrange
    const query = From.events().ofAnyType();
    // Act
    const reducer = query.build();
    // Assert
    expect(hamt.pairs(reducer.handledEventTypes)).to.deep.equal([
      [Constants.ALL_EVENT_TYPES, true]
    ]);
  });

  it('should have no handled events for constant structures', () => {
    // Arrange
    const structure = { foo: 'abc', bar: 'def' };
    const query = From.structure(structure);
    // Act
    const reducer = query.build();
    // Assert
    expect(hamt.count(reducer.handledEventTypes)).to.equal(0);
  });

  it('should handle the union of events handled by reducer properties in structure queries', () => {
    // Arrange
    const structure = {
      foo: 'abc',
      bar: From.value(10),
      baz: From.events().ofType('event-type-a').select(e => e.value),
      woo: From.events().ofType('event-type-b')
    };
    const query = From.structure(structure);
    // Act
    const reducer = query.build();
    // Assert
    expect(hamt.pairs(reducer.handledEventTypes)).to.deep.equal([
      ['event-type-a', true],
      ['event-type-b', true]
    ]);
  });

  it('should handle "abc" events for query From.events().ofType("abc").select(_ => 1).sum(0)', () => {
    // Arrange
    const query = From.events().ofType('abc').select(_ => 1).sum(0);
    // Act
    const reducer = query.build();
    // Assert
    expect(hamt.pairs(reducer.handledEventTypes)).to.deep.equal([
      ['abc', true]
    ]);
  });
  */
});<|endoftext|>


<commit_before>const { Plugin } = require('@uppy/core')
const cuid = require('cuid')
const Translator = require('@uppy/utils/lib/Translator')
const { Provider, RequestClient, Socket } = require('@uppy/companion-client')
const emitSocketProgress = require('@uppy/utils/lib/emitSocketProgress')
const getSocketHost = require('@uppy/utils/lib/getSocketHost')
const settle = require('@uppy/utils/lib/settle')
const limitPromises = require('@uppy/utils/lib/limitPromises')

function buildResponseError (xhr, error) {
  // No error message
  if (!error) error = new Error('Upload error')
  // Got an error message string
  if (typeof error === 'string') error = new Error(error)
  // Got something else
  if (!(error instanceof Error)) {
    error = Object.assign(new Error('Upload error'), { data: error })
  }

  error.request = xhr
  return error
}

module.exports = class XHRUpload extends Plugin {
  constructor (uppy, opts) {
    super(uppy, opts)
    this.type = 'uploader'
    this.id = 'XHRUpload'
    this.title = 'XHRUpload'

    this.defaultLocale = {
      strings: {
        timedOut: 'Upload stalled for %{seconds} seconds, aborting.'
      }
    }

    // Default options
    const defaultOptions = {
      formData: true,
      fieldName: 'files[]',
      method: 'post',
      metaFields: null,
      responseUrlFieldName: 'url',
      bundle: false,
      headers: {},
      timeout: 30 * 1000,
      limit: 0,
      withCredentials: false,
      responseType: '',
      /**
       * @typedef respObj
       * @property {string} responseText
       * @property {number} status
       * @property {string} statusText
       * @property {Object.<string, string>} headers
       *
       * @param {string} responseText the response body string
       * @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
       */
      getResponseData (responseText, response) {
        let parsedResponse = {}
        try {
          parsedResponse = JSON.parse(responseText)
        } catch (err) {
          console.log(err)
        }

        return parsedResponse
      },
      /**
       *
       * @param {string} responseText the response body string
       * @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
       */
      getResponseError (responseText, response) {
        return new Error('Upload error')
      },
      /**
       * @param {number} status the response status code
       * @param {string} responseText the response body string
       * @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
       */
      validateStatus (status, responseText, response) {
        return status >= 200 && status < 300
      }
    }

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

    // i18n
    this.translator = new Translator([ this.defaultLocale, this.uppy.locale, this.opts.locale ])
    this.i18n = this.translator.translate.bind(this.translator)
    this.i18nArray = this.translator.translateArray.bind(this.translator)

    this.handleUpload = this.handleUpload.bind(this)

    // Simultaneous upload limiting is shared across all uploads with this plugin.
    if (typeof this.opts.limit === 'number' && this.opts.limit !== 0) {
      this.limitUploads = limitPromises(this.opts.limit)
    } else {
      this.limitUploads = (fn) => fn
    }

    if (this.opts.bundle && !this.opts.formData) {
      throw new Error('`opts.formData` must be true when `opts.bundle` is enabled.')
    }
  }

  getOptions (file) {
    const overrides = this.uppy.getState().xhrUpload
    const opts = Object.assign({},
      this.opts,
      overrides || {},
      file.xhrUpload || {}
    )
    opts.headers = {}
    Object.assign(opts.headers, this.opts.headers)
    if (overrides) {
      Object.assign(opts.headers, overrides.headers)
    }
    if (file.xhrUpload) {
      Object.assign(opts.headers, file.xhrUpload.headers)
    }

    return opts
  }

  // Helper to abort upload requests if there has not been any progress for `timeout` ms.
  // Create an instance using `timer = createProgressTimeout(10000, onTimeout)`
  // Call `timer.progress()` to signal that there has been progress of any kind.
  // Call `timer.done()` when the upload has completed.
  createProgressTimeout (timeout, timeoutHandler) {
    const uppy = this.uppy
    const self = this
    let isDone = false

    function onTimedOut () {
      uppy.log(`[XHRUpload] timed out`)
      const error = new Error(self.i18n('timedOut', { seconds: Math.ceil(timeout / 1000) }))
      timeoutHandler(error)
    }

    let aliveTimer = null
    function progress () {
      // Some browsers fire another progress event when the upload is
      // cancelled, so we have to ignore progress after the timer was
      // told to stop.
      if (isDone) return

      if (timeout > 0) {
        if (aliveTimer) clearTimeout(aliveTimer)
        aliveTimer = setTimeout(onTimedOut, timeout)
      }
    }

    function done () {
      uppy.log(`[XHRUpload] timer done`)
      if (aliveTimer) {
        clearTimeout(aliveTimer)
        aliveTimer = null
      }
      isDone = true
    }

    return {
      progress,
      done
    }
  }

  createFormDataUpload (file, opts) {
    const formPost = new FormData()

    const metaFields = Array.isArray(opts.metaFields)
      ? opts.metaFields
      // Send along all fields by default.
      : Object.keys(file.meta)
    metaFields.forEach((item) => {
      formPost.append(item, file.meta[item])
    })

    if (file.name) {
      formPost.append(opts.fieldName, file.data, file.name)
    } else {
      formPost.append(opts.fieldName, file.data)
    }

    return formPost
  }

  createBareUpload (file, opts) {
    return file.data
  }

  upload (file, current, total) {
    const opts = this.getOptions(file)

    this.uppy.log(`uploading ${current} of ${total}`)
    return new Promise((resolve, reject) => {
      const data = opts.formData
        ? this.createFormDataUpload(file, opts)
        : this.createBareUpload(file, opts)

      const timer = this.createProgressTimeout(opts.timeout, (error) => {
        xhr.abort()
        this.uppy.emit('upload-error', file, error)
        reject(error)
      })

      const xhr = new XMLHttpRequest()

      const id = cuid()

      xhr.upload.addEventListener('loadstart', (ev) => {
        this.uppy.log(`[XHRUpload] ${id} started`)
      })

      xhr.upload.addEventListener('progress', (ev) => {
        this.uppy.log(`[XHRUpload] ${id} progress: ${ev.loaded} / ${ev.total}`)
        // Begin checking for timeouts when progress starts, instead of loading,
        // to avoid timing out requests on browser concurrency queue
        timer.progress()

        if (ev.lengthComputable) {
          this.uppy.emit('upload-progress', file, {
            uploader: this,
            bytesUploaded: ev.loaded,
            bytesTotal: ev.total
          })
        }
      })

      xhr.addEventListener('load', (ev) => {
        this.uppy.log(`[XHRUpload] ${id} finished`)
        timer.done()

        if (opts.validateStatus(ev.target.status, xhr.responseText, xhr)) {
          const body = opts.getResponseData(xhr.responseText, xhr)
          const uploadURL = body[opts.responseUrlFieldName]

          const uploadResp = {
            status: ev.target.status,
            body,
            uploadURL
          }

          this.uppy.emit('upload-success', file, uploadResp)

          if (uploadURL) {
            this.uppy.log(`Download ${file.name} from ${file.uploadURL}`)
          }

          return resolve(file)
        } else {
          const body = opts.getResponseData(xhr.responseText, xhr)
          const error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr))

          const response = {
            status: ev.target.status,
            body
          }

          this.uppy.emit('upload-error', file, error, response)
          return reject(error)
        }
      })

      xhr.addEventListener('error', (ev) => {
        this.uppy.log(`[XHRUpload] ${id} errored`)
        timer.done()

        const error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr))
        this.uppy.emit('upload-error', file, error)
        return reject(error)
      })

      xhr.open(opts.method.toUpperCase(), opts.endpoint, true)
      // IE10 does not allow setting `withCredentials` and `responseType`
      // before `open()` is called.
      xhr.withCredentials = opts.withCredentials
      if (opts.responseType !== '') {
        xhr.responseType = opts.responseType
      }

      Object.keys(opts.headers).forEach((header) => {
        xhr.setRequestHeader(header, opts.headers[header])
      })

      xhr.send(data)

      this.uppy.on('file-removed', (removedFile) => {
        if (removedFile.id === file.id) {
          timer.done()
          xhr.abort()
          reject(new Error('File removed'))
        }
      })

      this.uppy.on('cancel-all', () => {
        timer.done()
        xhr.abort()
        reject(new Error('Upload cancelled'))
      })
    })
  }

  uploadRemote (file, current, total) {
    const opts = this.getOptions(file)
    return new Promise((resolve, reject) => {
      const fields = {}
      const metaFields = Array.isArray(opts.metaFields)
        ? opts.metaFields
        // Send along all fields by default.
        : Object.keys(file.meta)

      metaFields.forEach((name) => {
        fields[name] = file.meta[name]
      })

      const Client = file.remote.providerOptions.provider ? Provider : RequestClient
      const client = new Client(this.uppy, file.remote.providerOptions)
      client.post(
        file.remote.url,
        Object.assign({}, file.remote.body, {
          endpoint: opts.endpoint,
          size: file.data.size,
          fieldname: opts.fieldName,
          metadata: fields,
          headers: opts.headers
        })
      )
      .then((res) => {
        const token = res.token
        const host = getSocketHost(file.remote.companionUrl)
        const socket = new Socket({ target: `${host}/api/${token}` })

        socket.on('progress', (progressData) => emitSocketProgress(this, progressData, file))

        socket.on('success', (data) => {
          const body = opts.getResponseData(data.response.responseText, data.response)
          const uploadURL = body[opts.responseUrlFieldName]

          const uploadResp = {
            status: data.response.status,
            body,
            uploadURL
          }

          this.uppy.emit('upload-success', file, uploadResp)
          socket.close()
          return resolve()
        })

        socket.on('error', (errData) => {
          const resp = errData.response
          const error = resp
            ? opts.getResponseError(resp.responseText, resp)
            : Object.assign(new Error(errData.error.message), { cause: errData.error })
          this.uppy.emit('upload-error', file, error)
          reject(error)
        })
      })
    })
  }

  uploadBundle (files) {
    return new Promise((resolve, reject) => {
      const endpoint = this.opts.endpoint
      const method = this.opts.method

      const formData = new FormData()
      files.forEach((file, i) => {
        const opts = this.getOptions(file)
        formData.append(opts.fieldName, file.data)
      })

      const xhr = new XMLHttpRequest()

      const timer = this.createProgressTimeout(this.opts.timeout, (error) => {
        xhr.abort()
        emitError(error)
        reject(error)
      })

      const emitError = (error) => {
        files.forEach((file) => {
          this.uppy.emit('upload-error', file, error)
        })
      }

      xhr.upload.addEventListener('loadstart', (ev) => {
        this.uppy.log('[XHRUpload] started uploading bundle')
        timer.progress()
      })

      xhr.upload.addEventListener('progress', (ev) => {
        timer.progress()

        if (!ev.lengthComputable) return

        files.forEach((file) => {
          this.uppy.emit('upload-progress', file, {
            uploader: this,
            bytesUploaded: ev.loaded / ev.total * file.size,
            bytesTotal: file.size
          })
        })
      })

      xhr.addEventListener('load', (ev) => {
        timer.done()

        if (this.opts.validateStatus(ev.target.status, xhr.responseText, xhr)) {
          const body = this.opts.getResponseData(xhr.responseText, xhr)
          const uploadResp = {
            status: ev.target.status,
            body
          }
          files.forEach((file) => {
            this.uppy.emit('upload-success', file, uploadResp)
          })
          return resolve()
        }

        const error = this.opts.getResponseError(xhr.responseText, xhr) || new Error('Upload error')
        error.request = xhr
        emitError(error)
        return reject(error)
      })

      xhr.addEventListener('error', (ev) => {
        timer.done()

        const error = this.opts.getResponseError(xhr.responseText, xhr) || new Error('Upload error')
        emitError(error)
        return reject(error)
      })

      this.uppy.on('cancel-all', () => {
        timer.done()
        xhr.abort()
      })

      xhr.open(method.toUpperCase(), endpoint, true)
      // IE10 does not allow setting `withCredentials` and `responseType`
      // before `open()` is called.
      xhr.withCredentials = this.opts.withCredentials
      if (this.opts.responseType !== '') {
        xhr.responseType = this.opts.responseType
      }

      Object.keys(this.opts.headers).forEach((header) => {
        xhr.setRequestHeader(header, this.opts.headers[header])
      })

      xhr.send(formData)

      files.forEach((file) => {
        this.uppy.emit('upload-started', file)
      })
    })
  }

  uploadFiles (files) {
    const actions = files.map((file, i) => {
      const current = parseInt(i, 10) + 1
      const total = files.length

      if (file.error) {
        return () => Promise.reject(new Error(file.error))
      } else if (file.isRemote) {
        // We emit upload-started here, so that it's also emitted for files
        // that have to wait due to the `limit` option.
        this.uppy.emit('upload-started', file)
        return this.uploadRemote.bind(this, file, current, total)
      } else {
        this.uppy.emit('upload-started', file)
        return this.upload.bind(this, file, current, total)
      }
    })

    const promises = actions.map((action) => {
      const limitedAction = this.limitUploads(action)
      return limitedAction()
    })

    return settle(promises)
  }

  handleUpload (fileIDs) {
    if (fileIDs.length === 0) {
      this.uppy.log('[XHRUpload] No files to upload!')
      return Promise.resolve()
    }

    this.uppy.log('[XHRUpload] Uploading...')
    const files = fileIDs.map((fileID) => this.uppy.getFile(fileID))

    if (this.opts.bundle) {
      return this.uploadBundle(files)
    }

    return this.uploadFiles(files).then(() => null)
  }

  install () {
    if (this.opts.bundle) {
      const { capabilities } = this.uppy.getState()
      this.uppy.setState({
        capabilities: {
          ...capabilities,
          individualCancellation: false
        }
      })
    }

    this.uppy.addUploader(this.handleUpload)
  }

  uninstall () {
    if (this.opts.bundle) {
      const { capabilities } = this.uppy.getState()
      this.uppy.setState({
        capabilities: {
          ...capabilities,
          individualCancellation: true
        }
      })
    }

    this.uppy.removeUploader(this.handleUpload)
  }
}
<commit_msg>xhr-upload: add filename to FormData with `bundle: true` (#1487)<commit_after>const { Plugin } = require('@uppy/core')
const cuid = require('cuid')
const Translator = require('@uppy/utils/lib/Translator')
const { Provider, RequestClient, Socket } = require('@uppy/companion-client')
const emitSocketProgress = require('@uppy/utils/lib/emitSocketProgress')
const getSocketHost = require('@uppy/utils/lib/getSocketHost')
const settle = require('@uppy/utils/lib/settle')
const limitPromises = require('@uppy/utils/lib/limitPromises')

function buildResponseError (xhr, error) {
  // No error message
  if (!error) error = new Error('Upload error')
  // Got an error message string
  if (typeof error === 'string') error = new Error(error)
  // Got something else
  if (!(error instanceof Error)) {
    error = Object.assign(new Error('Upload error'), { data: error })
  }

  error.request = xhr
  return error
}

module.exports = class XHRUpload extends Plugin {
  constructor (uppy, opts) {
    super(uppy, opts)
    this.type = 'uploader'
    this.id = 'XHRUpload'
    this.title = 'XHRUpload'

    this.defaultLocale = {
      strings: {
        timedOut: 'Upload stalled for %{seconds} seconds, aborting.'
      }
    }

    // Default options
    const defaultOptions = {
      formData: true,
      fieldName: 'files[]',
      method: 'post',
      metaFields: null,
      responseUrlFieldName: 'url',
      bundle: false,
      headers: {},
      timeout: 30 * 1000,
      limit: 0,
      withCredentials: false,
      responseType: '',
      /**
       * @typedef respObj
       * @property {string} responseText
       * @property {number} status
       * @property {string} statusText
       * @property {Object.<string, string>} headers
       *
       * @param {string} responseText the response body string
       * @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
       */
      getResponseData (responseText, response) {
        let parsedResponse = {}
        try {
          parsedResponse = JSON.parse(responseText)
        } catch (err) {
          console.log(err)
        }

        return parsedResponse
      },
      /**
       *
       * @param {string} responseText the response body string
       * @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
       */
      getResponseError (responseText, response) {
        return new Error('Upload error')
      },
      /**
       * @param {number} status the response status code
       * @param {string} responseText the response body string
       * @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
       */
      validateStatus (status, responseText, response) {
        return status >= 200 && status < 300
      }
    }

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

    // i18n
    this.translator = new Translator([ this.defaultLocale, this.uppy.locale, this.opts.locale ])
    this.i18n = this.translator.translate.bind(this.translator)
    this.i18nArray = this.translator.translateArray.bind(this.translator)

    this.handleUpload = this.handleUpload.bind(this)

    // Simultaneous upload limiting is shared across all uploads with this plugin.
    if (typeof this.opts.limit === 'number' && this.opts.limit !== 0) {
      this.limitUploads = limitPromises(this.opts.limit)
    } else {
      this.limitUploads = (fn) => fn
    }

    if (this.opts.bundle && !this.opts.formData) {
      throw new Error('`opts.formData` must be true when `opts.bundle` is enabled.')
    }
  }

  getOptions (file) {
    const overrides = this.uppy.getState().xhrUpload
    const opts = Object.assign({},
      this.opts,
      overrides || {},
      file.xhrUpload || {}
    )
    opts.headers = {}
    Object.assign(opts.headers, this.opts.headers)
    if (overrides) {
      Object.assign(opts.headers, overrides.headers)
    }
    if (file.xhrUpload) {
      Object.assign(opts.headers, file.xhrUpload.headers)
    }

    return opts
  }

  // Helper to abort upload requests if there has not been any progress for `timeout` ms.
  // Create an instance using `timer = createProgressTimeout(10000, onTimeout)`
  // Call `timer.progress()` to signal that there has been progress of any kind.
  // Call `timer.done()` when the upload has completed.
  createProgressTimeout (timeout, timeoutHandler) {
    const uppy = this.uppy
    const self = this
    let isDone = false

    function onTimedOut () {
      uppy.log(`[XHRUpload] timed out`)
      const error = new Error(self.i18n('timedOut', { seconds: Math.ceil(timeout / 1000) }))
      timeoutHandler(error)
    }

    let aliveTimer = null
    function progress () {
      // Some browsers fire another progress event when the upload is
      // cancelled, so we have to ignore progress after the timer was
      // told to stop.
      if (isDone) return

      if (timeout > 0) {
        if (aliveTimer) clearTimeout(aliveTimer)
        aliveTimer = setTimeout(onTimedOut, timeout)
      }
    }

    function done () {
      uppy.log(`[XHRUpload] timer done`)
      if (aliveTimer) {
        clearTimeout(aliveTimer)
        aliveTimer = null
      }
      isDone = true
    }

    return {
      progress,
      done
    }
  }

  createFormDataUpload (file, opts) {
    const formPost = new FormData()

    const metaFields = Array.isArray(opts.metaFields)
      ? opts.metaFields
      // Send along all fields by default.
      : Object.keys(file.meta)
    metaFields.forEach((item) => {
      formPost.append(item, file.meta[item])
    })

    if (file.name) {
      formPost.append(opts.fieldName, file.data, file.name)
    } else {
      formPost.append(opts.fieldName, file.data)
    }

    return formPost
  }

  createBareUpload (file, opts) {
    return file.data
  }

  upload (file, current, total) {
    const opts = this.getOptions(file)

    this.uppy.log(`uploading ${current} of ${total}`)
    return new Promise((resolve, reject) => {
      const data = opts.formData
        ? this.createFormDataUpload(file, opts)
        : this.createBareUpload(file, opts)

      const timer = this.createProgressTimeout(opts.timeout, (error) => {
        xhr.abort()
        this.uppy.emit('upload-error', file, error)
        reject(error)
      })

      const xhr = new XMLHttpRequest()

      const id = cuid()

      xhr.upload.addEventListener('loadstart', (ev) => {
        this.uppy.log(`[XHRUpload] ${id} started`)
      })

      xhr.upload.addEventListener('progress', (ev) => {
        this.uppy.log(`[XHRUpload] ${id} progress: ${ev.loaded} / ${ev.total}`)
        // Begin checking for timeouts when progress starts, instead of loading,
        // to avoid timing out requests on browser concurrency queue
        timer.progress()

        if (ev.lengthComputable) {
          this.uppy.emit('upload-progress', file, {
            uploader: this,
            bytesUploaded: ev.loaded,
            bytesTotal: ev.total
          })
        }
      })

      xhr.addEventListener('load', (ev) => {
        this.uppy.log(`[XHRUpload] ${id} finished`)
        timer.done()

        if (opts.validateStatus(ev.target.status, xhr.responseText, xhr)) {
          const body = opts.getResponseData(xhr.responseText, xhr)
          const uploadURL = body[opts.responseUrlFieldName]

          const uploadResp = {
            status: ev.target.status,
            body,
            uploadURL
          }

          this.uppy.emit('upload-success', file, uploadResp)

          if (uploadURL) {
            this.uppy.log(`Download ${file.name} from ${file.uploadURL}`)
          }

          return resolve(file)
        } else {
          const body = opts.getResponseData(xhr.responseText, xhr)
          const error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr))

          const response = {
            status: ev.target.status,
            body
          }

          this.uppy.emit('upload-error', file, error, response)
          return reject(error)
        }
      })

      xhr.addEventListener('error', (ev) => {
        this.uppy.log(`[XHRUpload] ${id} errored`)
        timer.done()

        const error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr))
        this.uppy.emit('upload-error', file, error)
        return reject(error)
      })

      xhr.open(opts.method.toUpperCase(), opts.endpoint, true)
      // IE10 does not allow setting `withCredentials` and `responseType`
      // before `open()` is called.
      xhr.withCredentials = opts.withCredentials
      if (opts.responseType !== '') {
        xhr.responseType = opts.responseType
      }

      Object.keys(opts.headers).forEach((header) => {
        xhr.setRequestHeader(header, opts.headers[header])
      })

      xhr.send(data)

      this.uppy.on('file-removed', (removedFile) => {
        if (removedFile.id === file.id) {
          timer.done()
          xhr.abort()
          reject(new Error('File removed'))
        }
      })

      this.uppy.on('cancel-all', () => {
        timer.done()
        xhr.abort()
        reject(new Error('Upload cancelled'))
      })
    })
  }

  uploadRemote (file, current, total) {
    const opts = this.getOptions(file)
    return new Promise((resolve, reject) => {
      const fields = {}
      const metaFields = Array.isArray(opts.metaFields)
        ? opts.metaFields
        // Send along all fields by default.
        : Object.keys(file.meta)

      metaFields.forEach((name) => {
        fields[name] = file.meta[name]
      })

      const Client = file.remote.providerOptions.provider ? Provider : RequestClient
      const client = new Client(this.uppy, file.remote.providerOptions)
      client.post(
        file.remote.url,
        Object.assign({}, file.remote.body, {
          endpoint: opts.endpoint,
          size: file.data.size,
          fieldname: opts.fieldName,
          metadata: fields,
          headers: opts.headers
        })
      )
      .then((res) => {
        const token = res.token
        const host = getSocketHost(file.remote.companionUrl)
        const socket = new Socket({ target: `${host}/api/${token}` })

        socket.on('progress', (progressData) => emitSocketProgress(this, progressData, file))

        socket.on('success', (data) => {
          const body = opts.getResponseData(data.response.responseText, data.response)
          const uploadURL = body[opts.responseUrlFieldName]

          const uploadResp = {
            status: data.response.status,
            body,
            uploadURL
          }

          this.uppy.emit('upload-success', file, uploadResp)
          socket.close()
          return resolve()
        })

        socket.on('error', (errData) => {
          const resp = errData.response
          const error = resp
            ? opts.getResponseError(resp.responseText, resp)
            : Object.assign(new Error(errData.error.message), { cause: errData.error })
          this.uppy.emit('upload-error', file, error)
          reject(error)
        })
      })
    })
  }

  uploadBundle (files) {
    return new Promise((resolve, reject) => {
      const endpoint = this.opts.endpoint
      const method = this.opts.method

      const formData = new FormData()
      files.forEach((file, i) => {
        const opts = this.getOptions(file)

        if (file.name) {
          formData.append(opts.fieldName, file.data, file.name)
        } else {
          formData.append(opts.fieldName, file.data)
        }
      })

      const xhr = new XMLHttpRequest()

      const timer = this.createProgressTimeout(this.opts.timeout, (error) => {
        xhr.abort()
        emitError(error)
        reject(error)
      })

      const emitError = (error) => {
        files.forEach((file) => {
          this.uppy.emit('upload-error', file, error)
        })
      }

      xhr.upload.addEventListener('loadstart', (ev) => {
        this.uppy.log('[XHRUpload] started uploading bundle')
        timer.progress()
      })

      xhr.upload.addEventListener('progress', (ev) => {
        timer.progress()

        if (!ev.lengthComputable) return

        files.forEach((file) => {
          this.uppy.emit('upload-progress', file, {
            uploader: this,
            bytesUploaded: ev.loaded / ev.total * file.size,
            bytesTotal: file.size
          })
        })
      })

      xhr.addEventListener('load', (ev) => {
        timer.done()

        if (this.opts.validateStatus(ev.target.status, xhr.responseText, xhr)) {
          const body = this.opts.getResponseData(xhr.responseText, xhr)
          const uploadResp = {
            status: ev.target.status,
            body
          }
          files.forEach((file) => {
            this.uppy.emit('upload-success', file, uploadResp)
          })
          return resolve()
        }

        const error = this.opts.getResponseError(xhr.responseText, xhr) || new Error('Upload error')
        error.request = xhr
        emitError(error)
        return reject(error)
      })

      xhr.addEventListener('error', (ev) => {
        timer.done()

        const error = this.opts.getResponseError(xhr.responseText, xhr) || new Error('Upload error')
        emitError(error)
        return reject(error)
      })

      this.uppy.on('cancel-all', () => {
        timer.done()
        xhr.abort()
      })

      xhr.open(method.toUpperCase(), endpoint, true)
      // IE10 does not allow setting `withCredentials` and `responseType`
      // before `open()` is called.
      xhr.withCredentials = this.opts.withCredentials
      if (this.opts.responseType !== '') {
        xhr.responseType = this.opts.responseType
      }

      Object.keys(this.opts.headers).forEach((header) => {
        xhr.setRequestHeader(header, this.opts.headers[header])
      })

      xhr.send(formData)

      files.forEach((file) => {
        this.uppy.emit('upload-started', file)
      })
    })
  }

  uploadFiles (files) {
    const actions = files.map((file, i) => {
      const current = parseInt(i, 10) + 1
      const total = files.length

      if (file.error) {
        return () => Promise.reject(new Error(file.error))
      } else if (file.isRemote) {
        // We emit upload-started here, so that it's also emitted for files
        // that have to wait due to the `limit` option.
        this.uppy.emit('upload-started', file)
        return this.uploadRemote.bind(this, file, current, total)
      } else {
        this.uppy.emit('upload-started', file)
        return this.upload.bind(this, file, current, total)
      }
    })

    const promises = actions.map((action) => {
      const limitedAction = this.limitUploads(action)
      return limitedAction()
    })

    return settle(promises)
  }

  handleUpload (fileIDs) {
    if (fileIDs.length === 0) {
      this.uppy.log('[XHRUpload] No files to upload!')
      return Promise.resolve()
    }

    this.uppy.log('[XHRUpload] Uploading...')
    const files = fileIDs.map((fileID) => this.uppy.getFile(fileID))

    if (this.opts.bundle) {
      return this.uploadBundle(files)
    }

    return this.uploadFiles(files).then(() => null)
  }

  install () {
    if (this.opts.bundle) {
      const { capabilities } = this.uppy.getState()
      this.uppy.setState({
        capabilities: {
          ...capabilities,
          individualCancellation: false
        }
      })
    }

    this.uppy.addUploader(this.handleUpload)
  }

  uninstall () {
    if (this.opts.bundle) {
      const { capabilities } = this.uppy.getState()
      this.uppy.setState({
        capabilities: {
          ...capabilities,
          individualCancellation: true
        }
      })
    }

    this.uppy.removeUploader(this.handleUpload)
  }
}
<|endoftext|>


<commit_before>'use strict';

var Path = require('path');
var expect = require('unexpected').clone();
var tolk = require('../lib/baby-tolk');

function getPath(path) {
  return Path.join(process.cwd(), 'fixtures/source', path);
}

describe('readCompiled', function () {
  it('should read a file directly if there is no adapter', function () {
    return expect(tolk.read(getPath('unchanged.txt')), 'to be fulfilled with', {
      result: 'I am the same\n'
    });
  });

  it('should throw when reading a file that does not exist', function () {
    return expect(tolk.read(getPath('does-not-exist.txt')), 'when rejected', 'to satisfy', {
      code: 'ENOENT',
      path: /fixtures\/source\/does-not-exist\.txt$/,
      message: /^ENOENT.*?, open '.+?fixtures\/source\/does-not-exist\.txt'$/
    });
  });

  it('should compile a file if there is an adapter', function () {
    this.timeout(5000);
    return expect(tolk.read(getPath('babel/simplest.jsx'), { presets: ['es2015'] }), 'to be fulfilled with', {
      result: expect.it('to begin with', '\'use strict\';\n\nvar foo = \'bar\';'),
      extension: expect.it('to be', '.js'),
    });
  });

  it('should output source map if there is an adapter that supports source maps', function () {
    return expect(tolk.read(getPath('less/external.less')), 'to be fulfilled with', {
      sourcemap: {
        sources: expect.it('to have length', 2),
        mappings: expect.it('to begin with', 'AAAA;EACE,')
      }
    });
  });

  it('should have a fix for issue #1 (buggy uglifyJS2)', function () {
    return expect(tolk.read(getPath('coffee/basic.coffee'), {minify: true}), 'to be fulfilled with', {
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'CAAA,WAAAA'),
        file: expect.it('to be', 'basic.js')
      }
    });
  });

  it('should support CSS minification (with compilation)', function () {
    return expect(tolk.read(getPath('less/external.less'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '.bar{wow:\'foo\'}'),
      sourcemap: {
        sources: expect.it('to have length', 2),
        mappings: expect.it('to begin with', 'AAAA,KACE,')
      }
    });
  });

  it('should support CSS minification (without compilation)', function () {
    return expect(tolk.read(getPath('csso/basic.css'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '/*! keep this comment */.hello{margin:0;color:silver'),
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'wBAGA,OACE,')
      }
    });
  });

  it('should support JS minification (with compilation)', function () {
    return expect(tolk.read(getPath('coffee/basic.coffee'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '(function(){console.log(15)})'),
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'CAAA,WAAAA')
      }
    });
  });

  it('should support JS minification (without compilation)', function () {
    return expect(tolk.read(getPath('minify-js/basic.js'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', 'for(var stuff=[1,2,3,4,5],i=0;i<stuff.length;i++)'),
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'AACA,IAAK,')
      }
    });
  });

  it('should support HTML minification (with compilation)', function () {
    return expect(tolk.read(getPath('jade/client-complex.jade'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '
1

1

2

2

3

3

4

4

')
    });
  });

  it('should support HTML minification (without compilation)', function () {
    return expect(tolk.read(getPath('minify-html/basic.html'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '

wowlaween

')
    });
  });

  it('should not compile files beginning with underscore', function () {
    return expect(tolk.read(getPath('scss/_mixin_lib.scss'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '@mixin set_color($color) {\n  color: $color;')
    });
  });

  it('should throw when compiling a file that does not exist', function () {
    return expect(tolk.read(getPath('does-not-exist.scss')), 'when rejected', 'to satisfy', {
      code: 'ENOENT',
      path: /fixtures\/source\/does-not-exist\.scss$/,
      message: /^ENOENT.*?, open '.+?fixtures\/source\/does-not-exist\.scss'$/
    });
  });

  it('should throw when compiling a file with syntax errors', function () {
    return expect(tolk.read(getPath('scss/syntaxerror.scss')), 'when rejected', 'to satisfy', {
      status: 1,
      file: /fixtures\/source\/scss\/syntaxerror\.scss$/,
      line: 2,
      column: 3,
      message: 'property "color" must be followed by a \':\'',
    });
  });

});
<commit_msg>Increase test timeout because it sometimes fails on Node 4.<commit_after>'use strict';

var Path = require('path');
var expect = require('unexpected').clone();
var tolk = require('../lib/baby-tolk');

function getPath(path) {
  return Path.join(process.cwd(), 'fixtures/source', path);
}

describe('readCompiled', function () {
  it('should read a file directly if there is no adapter', function () {
    return expect(tolk.read(getPath('unchanged.txt')), 'to be fulfilled with', {
      result: 'I am the same\n'
    });
  });

  it('should throw when reading a file that does not exist', function () {
    return expect(tolk.read(getPath('does-not-exist.txt')), 'when rejected', 'to satisfy', {
      code: 'ENOENT',
      path: /fixtures\/source\/does-not-exist\.txt$/,
      message: /^ENOENT.*?, open '.+?fixtures\/source\/does-not-exist\.txt'$/
    });
  });

  it('should compile a file if there is an adapter', function () {
    this.timeout(10000);
    return expect(tolk.read(getPath('babel/simplest.jsx'), { presets: ['es2015'] }), 'to be fulfilled with', {
      result: expect.it('to begin with', '\'use strict\';\n\nvar foo = \'bar\';'),
      extension: expect.it('to be', '.js'),
    });
  });

  it('should output source map if there is an adapter that supports source maps', function () {
    return expect(tolk.read(getPath('less/external.less')), 'to be fulfilled with', {
      sourcemap: {
        sources: expect.it('to have length', 2),
        mappings: expect.it('to begin with', 'AAAA;EACE,')
      }
    });
  });

  it('should have a fix for issue #1 (buggy uglifyJS2)', function () {
    return expect(tolk.read(getPath('coffee/basic.coffee'), {minify: true}), 'to be fulfilled with', {
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'CAAA,WAAAA'),
        file: expect.it('to be', 'basic.js')
      }
    });
  });

  it('should support CSS minification (with compilation)', function () {
    return expect(tolk.read(getPath('less/external.less'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '.bar{wow:\'foo\'}'),
      sourcemap: {
        sources: expect.it('to have length', 2),
        mappings: expect.it('to begin with', 'AAAA,KACE,')
      }
    });
  });

  it('should support CSS minification (without compilation)', function () {
    return expect(tolk.read(getPath('csso/basic.css'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '/*! keep this comment */.hello{margin:0;color:silver'),
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'wBAGA,OACE,')
      }
    });
  });

  it('should support JS minification (with compilation)', function () {
    return expect(tolk.read(getPath('coffee/basic.coffee'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '(function(){console.log(15)})'),
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'CAAA,WAAAA')
      }
    });
  });

  it('should support JS minification (without compilation)', function () {
    return expect(tolk.read(getPath('minify-js/basic.js'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', 'for(var stuff=[1,2,3,4,5],i=0;i<stuff.length;i++)'),
      sourcemap: {
        sources: expect.it('to have length', 1),
        mappings: expect.it('to begin with', 'AACA,IAAK,')
      }
    });
  });

  it('should support HTML minification (with compilation)', function () {
    return expect(tolk.read(getPath('jade/client-complex.jade'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '
1

1

2

2

3

3

4

4

')
    });
  });

  it('should support HTML minification (without compilation)', function () {
    return expect(tolk.read(getPath('minify-html/basic.html'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '

wowlaween

')
    });
  });

  it('should not compile files beginning with underscore', function () {
    return expect(tolk.read(getPath('scss/_mixin_lib.scss'), {minify: true}), 'to be fulfilled with', {
      result: expect.it('to begin with', '@mixin set_color($color) {\n  color: $color;')
    });
  });

  it('should throw when compiling a file that does not exist', function () {
    return expect(tolk.read(getPath('does-not-exist.scss')), 'when rejected', 'to satisfy', {
      code: 'ENOENT',
      path: /fixtures\/source\/does-not-exist\.scss$/,
      message: /^ENOENT.*?, open '.+?fixtures\/source\/does-not-exist\.scss'$/
    });
  });

  it('should throw when compiling a file with syntax errors', function () {
    return expect(tolk.read(getPath('scss/syntaxerror.scss')), 'when rejected', 'to satisfy', {
      status: 1,
      file: /fixtures\/source\/scss\/syntaxerror\.scss$/,
      line: 2,
      column: 3,
      message: 'property "color" must be followed by a \':\'',
    });
  });

});
<|endoftext|>


<commit_before>$p.openChangePasswordDialog = function () {
    var data = $p.getData($('#ChangePasswordForm'));
    data.Users_LoginId = $('#Users_LoginId').val();
    data.Users_OldPassword = $('#Users_Password').val();
    data.ReturnUrl = $('#ReturnUrl').val();
    $('#ChangePasswordDialog').dialog({
        modal: true,
        width: '420px'
    });
}

$p.changePasswordAtLogin = function ($control) {
    var data = $p.getData('ChangePasswordForm');
    data.Users_LoginId = $('#Users_LoginId').val();
    data.Users_Password = $('#Users_Password').val();
    $p.send($control, 'ChangePasswordForm');
}<commit_msg>Refactored: formIdの指定を省略。<commit_after>$p.openChangePasswordDialog = function () {
    var data = $p.getData($('#ChangePasswordForm'));
    data.Users_LoginId = $('#Users_LoginId').val();
    data.Users_OldPassword = $('#Users_Password').val();
    data.ReturnUrl = $('#ReturnUrl').val();
    $('#ChangePasswordDialog').dialog({
        modal: true,
        width: '420px'
    });
}

$p.changePasswordAtLogin = function ($control) {
    var data = $p.getData('ChangePasswordForm');
    data.Users_LoginId = $('#Users_LoginId').val();
    data.Users_Password = $('#Users_Password').val();
    $p.send($control);
}<|endoftext|>


<commit_before>//@flow
import type { Unit } from "./types";
import numeral from "numeral";

/**
 * This will format in a very concise way a valid, typically to be used on axis.
 * For instance 15k 20k ,...
 */
export function formatShort(
  unit: Unit,
  value: number,
  locale: string = "en-EN"
): string {
  const { magnitude } = unit;
  const floatValue = value / 10 ** magnitude;
  return numeral(floatValue)
    .locale(locale)
    .format("0.0a");
}
<commit_msg>numeral locale is not reliable. don't use it for now.<commit_after>//@flow
import type { Unit } from "./types";
import numeral from "numeral";

/**
 * This will format in a very concise way a valid, typically to be used on axis.
 * For instance 15k 20k ,...
 */
export function formatShort(unit: Unit, value: number): string {
  const { magnitude } = unit;
  const floatValue = value / 10 ** magnitude;
  return numeral(floatValue).format("0.0a");
}
<|endoftext|>


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

module.exports = {
  rules: {
    'prettier/prettier': [
      'error',
      Object.assign({}, baseConfig.rules['prettier/prettier'][1], {
        trailingComma: 'es5',
      }),
    ],
  },
};
<commit_msg>chore: fix lint issues<commit_after>const baseConfig = require('.');

module.exports = {
  rules: {
    'prettier/prettier': [
      'error',
      Object.assign({}, baseConfig.rules['prettier/prettier'][1], {
        trailingComma: 'es5',
      }),
    ],
  },
};
<|endoftext|>


<commit_before>/* @flow */

import globalContext from './globalContext';

import {
  Type,
  TypeParameter,
  TypeBox,
  TypeReference,
  TypeTDZ,
  ParameterizedTypeAlias,
  TypeAlias,
  TypeConstructor,
  GenericType,
  NullLiteralType,
  NumberType,
  NumericLiteralType,
  BooleanType,
  BooleanLiteralType,
  SymbolType,
  SymbolLiteralType,
  StringType,
  StringLiteralType,
  ArrayType,
  ObjectType,
  ObjectTypeCallProperty,
  ObjectTypeIndexer,
  ObjectTypeProperty,
  FlowIntoType,
  FunctionType,
  ParameterizedFunctionType,
  PartialType,
  FunctionTypeParam,
  FunctionTypeRestParam,
  FunctionTypeReturn,
  GeneratorType,
  ExistentialType,
  AnyType,
  MixedType,
  EmptyType,
  NullableType,
  ThisType,
  TupleType,
  UnionType,
  IntersectionType,
  VoidType,
  RefinementType,
  TypeParameterApplication
} from './types';

import {
  Declaration,
  TypeDeclaration,
  VarDeclaration,
  ModuleDeclaration,
  ModuleExportsDeclaration,
  ClassDeclaration,
  ParameterizedClassDeclaration,
  ExtendsDeclaration
} from './declarations';

import TypeContext from './TypeContext';

function defineProperty (name: string, value: any) {
  Object.defineProperty(globalContext, name, {
    value: value
  });
}

defineProperty('TypeContext', TypeContext);
defineProperty('Type', Type);
defineProperty('TypeBox', TypeBox);
defineProperty('TypeParameter', TypeParameter);
defineProperty('TypeReference', TypeReference);
defineProperty('TypeTDZ', TypeTDZ);
defineProperty('ParameterizedTypeAlias', ParameterizedTypeAlias);
defineProperty('TypeAlias', TypeAlias);
defineProperty('TypeConstructor', TypeConstructor);
defineProperty('GenericType', GenericType);
defineProperty('NullLiteralType', NullLiteralType);
defineProperty('NumberType', NumberType);
defineProperty('NumericLiteralType', NumericLiteralType);
defineProperty('BooleanType', BooleanType);
defineProperty('BooleanLiteralType', BooleanLiteralType);
defineProperty('SymbolType', SymbolType);
defineProperty('SymbolLiteralType', SymbolLiteralType);
defineProperty('StringType', StringType);
defineProperty('StringLiteralType', StringLiteralType);
defineProperty('ArrayType', ArrayType);
defineProperty('ObjectType', ObjectType);
defineProperty('ObjectTypeCallProperty', ObjectTypeCallProperty);
defineProperty('ObjectTypeIndexer', ObjectTypeIndexer);
defineProperty('ObjectTypeProperty', ObjectTypeProperty);
defineProperty('FunctionType', FunctionType);
defineProperty('FunctionTypeParam', FunctionTypeParam);
defineProperty('FunctionTypeRestParam', FunctionTypeRestParam);
defineProperty('FunctionTypeReturn', FunctionTypeReturn);
defineProperty('ParameterizedFunctionType', ParameterizedFunctionType);
defineProperty('PartialType', PartialType);
defineProperty('RefinementType', RefinementType);
defineProperty('TypeParameterApplication', TypeParameterApplication);
defineProperty('GeneratorType', GeneratorType);
defineProperty('ExistentialType', ExistentialType);
defineProperty('FlowIntoType', FlowIntoType);
defineProperty('AnyType', AnyType);
defineProperty('MixedType', MixedType);
defineProperty('EmptyType', EmptyType);
defineProperty('NullableType', NullableType);
defineProperty('ThisType', ThisType);
defineProperty('TupleType', TupleType);
defineProperty('UnionType', UnionType);
defineProperty('IntersectionType', IntersectionType);
defineProperty('VoidType', VoidType);
defineProperty('Declaration', Declaration);
defineProperty('VarDeclaration', VarDeclaration);
defineProperty('TypeDeclaration', TypeDeclaration);
defineProperty('ModuleDeclaration', ModuleDeclaration);
defineProperty('ModuleExportsDeclaration', ModuleExportsDeclaration);
defineProperty('ClassDeclaration', ClassDeclaration);
defineProperty('ParameterizedClassDeclaration', ParameterizedClassDeclaration);
defineProperty('ExtendsDeclaration', ExtendsDeclaration);

export default globalContext;
<commit_msg>Fixes "Cannot redefine property: TypeContext"<commit_after>/* @flow */

import globalContext from './globalContext';

import {
  Type,
  TypeParameter,
  TypeBox,
  TypeReference,
  TypeTDZ,
  ParameterizedTypeAlias,
  TypeAlias,
  TypeConstructor,
  GenericType,
  NullLiteralType,
  NumberType,
  NumericLiteralType,
  BooleanType,
  BooleanLiteralType,
  SymbolType,
  SymbolLiteralType,
  StringType,
  StringLiteralType,
  ArrayType,
  ObjectType,
  ObjectTypeCallProperty,
  ObjectTypeIndexer,
  ObjectTypeProperty,
  FlowIntoType,
  FunctionType,
  ParameterizedFunctionType,
  PartialType,
  FunctionTypeParam,
  FunctionTypeRestParam,
  FunctionTypeReturn,
  GeneratorType,
  ExistentialType,
  AnyType,
  MixedType,
  EmptyType,
  NullableType,
  ThisType,
  TupleType,
  UnionType,
  IntersectionType,
  VoidType,
  RefinementType,
  TypeParameterApplication
} from './types';

import {
  Declaration,
  TypeDeclaration,
  VarDeclaration,
  ModuleDeclaration,
  ModuleExportsDeclaration,
  ClassDeclaration,
  ParameterizedClassDeclaration,
  ExtendsDeclaration
} from './declarations';

import TypeContext from './TypeContext';

function v (thing) {
  return { value: thing }
}

if (typeof global !== 'undefined' && global.__FLOW_RUNTIME_GLOBAL_CONTEXT_DO_NOT_USE_THIS_VARIABLE__ !== globalContext) {
  Object.defineProperties(globalContext, {
    TypeContext: v(TypeContext),
    Type: v(Type),
    TypeBox: v(TypeBox),
    TypeParameter: v(TypeParameter),
    TypeReference: v(TypeReference),
    TypeTDZ: v(TypeTDZ),
    ParameterizedTypeAlias: v(ParameterizedTypeAlias),
    TypeAlias: v(TypeAlias),
    TypeConstructor: v(TypeConstructor),
    GenericType: v(GenericType),
    NullLiteralType: v(NullLiteralType),
    NumberType: v(NumberType),
    NumericLiteralType: v(NumericLiteralType),
    BooleanType: v(BooleanType),
    BooleanLiteralType: v(BooleanLiteralType),
    SymbolType: v(SymbolType),
    SymbolLiteralType: v(SymbolLiteralType),
    StringType: v(StringType),
    StringLiteralType: v(StringLiteralType),
    ArrayType: v(ArrayType),
    ObjectType: v(ObjectType),
    ObjectTypeCallProperty: v(ObjectTypeCallProperty),
    ObjectTypeIndexer: v(ObjectTypeIndexer),
    ObjectTypeProperty: v(ObjectTypeProperty),
    FunctionType: v(FunctionType),
    FunctionTypeParam: v(FunctionTypeParam),
    FunctionTypeRestParam: v(FunctionTypeRestParam),
    FunctionTypeReturn: v(FunctionTypeReturn),
    ParameterizedFunctionType: v(ParameterizedFunctionType),
    PartialType: v(PartialType),
    RefinementType: v(RefinementType),
    TypeParameterApplication: v(TypeParameterApplication),
    GeneratorType: v(GeneratorType),
    ExistentialType: v(ExistentialType),
    FlowIntoType: v(FlowIntoType),
    AnyType: v(AnyType),
    MixedType: v(MixedType),
    EmptyType: v(EmptyType),
    NullableType: v(NullableType),
    ThisType: v(ThisType),
    TupleType: v(TupleType),
    UnionType: v(UnionType),
    IntersectionType: v(IntersectionType),
    VoidType: v(VoidType),
    Declaration: v(Declaration),
    VarDeclaration: v(VarDeclaration),
    TypeDeclaration: v(TypeDeclaration),
    ModuleDeclaration: v(ModuleDeclaration),
    ModuleExportsDeclaration: v(ModuleExportsDeclaration),
    ClassDeclaration: v(ClassDeclaration),
    ParameterizedClassDeclaration: v(ParameterizedClassDeclaration),
    ExtendsDeclaration: v(ExtendsDeclaration),
  })
}

export default globalContext;
<|endoftext|>


<commit_before>/**
 * Adds Expo-related mocks to the Jest environment. Jest runs this setup module after it runs the
 * React Native setup module.
 */
'use strict';

// whatwg-fetch@3 expects "self" to be globally defined
global.self = global;

const { Response, Request, Headers, fetch } = require('whatwg-fetch');
global.Response = Response;
global.Request = Request;
global.Headers = Headers;
global.fetch = fetch;

const mockNativeModules = require('react-native/Libraries/BatchedBridge/NativeModules');
const createMockConstants = require('./createMockConstants');

// window isn't defined as of react-native 0.45+ it seems
if (typeof window !== 'object') {
  global.window = global;
  global.window.navigator = {};
}

const mockImageLoader = {
  configurable: true,
  enumerable: true,
  get: () => ({
    prefetchImage: jest.fn(),
    getSize: jest.fn((uri, success) => process.nextTick(() => success(320, 240))),
  }),
};
Object.defineProperty(mockNativeModules, 'ImageLoader', mockImageLoader);
Object.defineProperty(mockNativeModules, 'ImageViewManager', mockImageLoader);

Object.defineProperty(mockNativeModules, 'LinkingManager', {
  configurable: true,
  enumerable: true,
  get: () => mockNativeModules.Linking,
});

const mockPlatformConstants = {
  configurable: true,
  enumerable: true,
  get: () => ({
    forceTouchAvailable: true,
  }),
};
Object.defineProperty(mockNativeModules, 'PlatformConstants', mockPlatformConstants);

const publicExpoModules = require('./expoModules');
const internalExpoModules = require('./internalExpoModules');
const expoModules = {
  ...publicExpoModules,
  ...internalExpoModules,
};

function mock(property, customMock) {
  const propertyType = property.type;
  let mockValue;
  if (customMock !== undefined) {
    mockValue = customMock;
  } else if (propertyType === 'function') {
    if (property.functionType === 'promise') {
      mockValue = jest.fn(() => Promise.resolve());
    } else {
      mockValue = jest.fn();
    }
  } else if (propertyType === 'number') {
    mockValue = 1;
  } else if (propertyType === 'string') {
    mockValue = 'mock';
  } else if (propertyType === 'array') {
    mockValue = [];
  } else if (propertyType === 'mock') {
    mockValue = mockByMockDefinition(property.mockDefinition);
  } else {
    mockValue = {};
  }
  return mockValue;
}

function mockProperties(moduleProperties, customMocks) {
  const mockedProperties = {};
  for (let propertyName of Object.keys(moduleProperties)) {
    const property = moduleProperties[propertyName];
    const customMock =
      customMocks && customMocks.hasOwnProperty(propertyName)
        ? customMocks[propertyName]
        : property.mock;
    mockedProperties[propertyName] = mock(property, customMock);
  }
  return mockedProperties;
}

function mockByMockDefinition(definition) {
  const mock = {};
  for (const key of Object.keys(definition)) {
    mock[key] = mockProperties(definition[key]);
  }
  return mock;
}

for (let moduleName of Object.keys(expoModules)) {
  const moduleProperties = expoModules[moduleName];
  const mockedProperties = mockProperties(moduleProperties);

  Object.defineProperty(mockNativeModules, moduleName, {
    configurable: true,
    enumerable: true,
    get: () => mockedProperties,
  });
}

mockNativeModules.NativeUnimoduleProxy.viewManagersNames.forEach(viewManagerName => {
  Object.defineProperty(mockNativeModules.UIManager, `ViewManagerAdapter_${viewManagerName}`, {
    get: () => ({
      NativeProps: {},
      directEventTypes: [],
    }),
  });
});

// Needed for `react-native-gesture-handler` as of 10/29/2018
// Otherwise the following line fails with "cannot read property directEventTypes of undefined"
// https://github.com/kmagiera/react-native-gesture-handler/blob/master/GestureHandler.js#L46
Object.defineProperty(mockNativeModules.UIManager, 'RCTView', {
  get: () => ({
    NativeProps: {},
    directEventTypes: [],
  }),
});

Object.defineProperty(mockNativeModules.UIManager, 'takeSnapshot', {
  configurable: true,
  enumerable: true,
  writable: true,
  value: jest.fn(),
});

const modulesConstants = mockNativeModules.NativeUnimoduleProxy.modulesConstants;
mockNativeModules.NativeUnimoduleProxy.modulesConstants = {
  ...modulesConstants,
  ExponentConstants: {
    ...modulesConstants.ExponentConstants,
    ...createMockConstants(),
  },
};

jest.mock('expo-file-system', () => ({
  FileSystem: {
    downloadAsync: jest.fn(() => Promise.resolve({ md5: 'md5', uri: 'uri' })),
    getInfoAsync: jest.fn(() => Promise.resolve({ exists: true, md5: 'md5', uri: 'uri' })),
    readAsStringAsync: jest.fn(),
    writeAsStringAsync: jest.fn(),
    deleteAsync: jest.fn(),
    moveAsync: jest.fn(),
    copyAsync: jest.fn(),
    makeDirectoryAsync: jest.fn(),
    readDirectoryAsync: jest.fn(),
    createDownloadResumable: jest.fn(),
  },
}));

jest.mock('react-native/Libraries/Image/AssetRegistry', () => ({
  registerAsset: jest.fn(() => 1),
  getAssetByID: jest.fn(() => ({
    fileSystemLocation: '/full/path/to/directory',
    httpServerLocation: '/assets/full/path/to/directory',
    scales: [1],
    fileHashes: ['md5'],
    name: 'name',
    exists: true,
    type: 'type',
    hash: 'md5',
    uri: 'uri',
    width: 1,
    height: 1,
  })),
}));

jest.mock('react-native-gesture-handler', () => {
  const View = require('react-native/Libraries/Components/View/View');
  return {
    Swipeable: View,
    DrawerLayout: View,
    State: {},
    ScrollView: View,
    Slider: View,
    Switch: View,
    TextInput: View,
    ToolbarAndroid: View,
    ViewPagerAndroid: View,
    DrawerLayoutAndroid: View,
    WebView: View,
    NativeViewGestureHandler: View,
    TapGestureHandler: View,
    FlingGestureHandler: View,
    ForceTouchGestureHandler: View,
    LongPressGestureHandler: View,
    PanGestureHandler: View,
    PinchGestureHandler: View,
    RotationGestureHandler: View,
    /* Buttons */
    RawButton: View,
    BaseButton: View,
    RectButton: View,
    BorderlessButton: View,
    /* Other */
    FlatList: View,
    gestureHandlerRootHOC: jest.fn(),
    Directions: {},
  };
});

jest.doMock('react-native/Libraries/BatchedBridge/NativeModules', () => mockNativeModules);

jest.mock('@unimodules/react-native-adapter', () => {
  const ReactNativeAdapter = require.requireActual('@unimodules/react-native-adapter');
  const { NativeModulesProxy } = ReactNativeAdapter;

  // After the NativeModules mock is set up, we can mock NativeModuleProxy's functions that call
  // into the native proxy module. We're not really interested in checking whether the underlying
  // method is called, just that the proxy method is called, since we have unit tests for the
  // adapter and believe it works correctly.
  //
  // NOTE: The adapter validates the number of arguments, which we don't do in the mocked functions.
  // This means the mock functions will not throw validation errors the way they would in an app.
  for (const moduleName of Object.keys(NativeModulesProxy)) {
    const nativeModule = NativeModulesProxy[moduleName];
    for (const propertyName of Object.keys(nativeModule)) {
      if (typeof nativeModule[propertyName] === 'function') {
        nativeModule[propertyName] = jest.fn(async () => {});
      }
    }
  }

  return ReactNativeAdapter;
});

// The UIManager module is not idempotent and causes issues if we load it again after resetting
// the modules with Jest.
let UIManager;
jest.doMock('react-native/Libraries/ReactNative/UIManager', () => {
  if (!UIManager) {
    UIManager = require.requireActual('react-native/Libraries/ReactNative/UIManager');
  }
  return UIManager;
});
<commit_msg>[jest] Fix expo-file-system mocks by unscoping methods (#4520)<commit_after>/**
 * Adds Expo-related mocks to the Jest environment. Jest runs this setup module after it runs the
 * React Native setup module.
 */
'use strict';

// whatwg-fetch@3 expects "self" to be globally defined
global.self = global;

const { Response, Request, Headers, fetch } = require('whatwg-fetch');
global.Response = Response;
global.Request = Request;
global.Headers = Headers;
global.fetch = fetch;

const mockNativeModules = require('react-native/Libraries/BatchedBridge/NativeModules');
const createMockConstants = require('./createMockConstants');

// window isn't defined as of react-native 0.45+ it seems
if (typeof window !== 'object') {
  global.window = global;
  global.window.navigator = {};
}

const mockImageLoader = {
  configurable: true,
  enumerable: true,
  get: () => ({
    prefetchImage: jest.fn(),
    getSize: jest.fn((uri, success) => process.nextTick(() => success(320, 240))),
  }),
};
Object.defineProperty(mockNativeModules, 'ImageLoader', mockImageLoader);
Object.defineProperty(mockNativeModules, 'ImageViewManager', mockImageLoader);

Object.defineProperty(mockNativeModules, 'LinkingManager', {
  configurable: true,
  enumerable: true,
  get: () => mockNativeModules.Linking,
});

const mockPlatformConstants = {
  configurable: true,
  enumerable: true,
  get: () => ({
    forceTouchAvailable: true,
  }),
};
Object.defineProperty(mockNativeModules, 'PlatformConstants', mockPlatformConstants);

const publicExpoModules = require('./expoModules');
const internalExpoModules = require('./internalExpoModules');
const expoModules = {
  ...publicExpoModules,
  ...internalExpoModules,
};

function mock(property, customMock) {
  const propertyType = property.type;
  let mockValue;
  if (customMock !== undefined) {
    mockValue = customMock;
  } else if (propertyType === 'function') {
    if (property.functionType === 'promise') {
      mockValue = jest.fn(() => Promise.resolve());
    } else {
      mockValue = jest.fn();
    }
  } else if (propertyType === 'number') {
    mockValue = 1;
  } else if (propertyType === 'string') {
    mockValue = 'mock';
  } else if (propertyType === 'array') {
    mockValue = [];
  } else if (propertyType === 'mock') {
    mockValue = mockByMockDefinition(property.mockDefinition);
  } else {
    mockValue = {};
  }
  return mockValue;
}

function mockProperties(moduleProperties, customMocks) {
  const mockedProperties = {};
  for (let propertyName of Object.keys(moduleProperties)) {
    const property = moduleProperties[propertyName];
    const customMock =
      customMocks && customMocks.hasOwnProperty(propertyName)
        ? customMocks[propertyName]
        : property.mock;
    mockedProperties[propertyName] = mock(property, customMock);
  }
  return mockedProperties;
}

function mockByMockDefinition(definition) {
  const mock = {};
  for (const key of Object.keys(definition)) {
    mock[key] = mockProperties(definition[key]);
  }
  return mock;
}

for (let moduleName of Object.keys(expoModules)) {
  const moduleProperties = expoModules[moduleName];
  const mockedProperties = mockProperties(moduleProperties);

  Object.defineProperty(mockNativeModules, moduleName, {
    configurable: true,
    enumerable: true,
    get: () => mockedProperties,
  });
}

mockNativeModules.NativeUnimoduleProxy.viewManagersNames.forEach(viewManagerName => {
  Object.defineProperty(mockNativeModules.UIManager, `ViewManagerAdapter_${viewManagerName}`, {
    get: () => ({
      NativeProps: {},
      directEventTypes: [],
    }),
  });
});

// Needed for `react-native-gesture-handler` as of 10/29/2018
// Otherwise the following line fails with "cannot read property directEventTypes of undefined"
// https://github.com/kmagiera/react-native-gesture-handler/blob/master/GestureHandler.js#L46
Object.defineProperty(mockNativeModules.UIManager, 'RCTView', {
  get: () => ({
    NativeProps: {},
    directEventTypes: [],
  }),
});

Object.defineProperty(mockNativeModules.UIManager, 'takeSnapshot', {
  configurable: true,
  enumerable: true,
  writable: true,
  value: jest.fn(),
});

const modulesConstants = mockNativeModules.NativeUnimoduleProxy.modulesConstants;
mockNativeModules.NativeUnimoduleProxy.modulesConstants = {
  ...modulesConstants,
  ExponentConstants: {
    ...modulesConstants.ExponentConstants,
    ...createMockConstants(),
  },
};

jest.mock('expo-file-system', () => ({
  downloadAsync: jest.fn(() => Promise.resolve({ md5: 'md5', uri: 'uri' })),
  getInfoAsync: jest.fn(() => Promise.resolve({ exists: true, md5: 'md5', uri: 'uri' })),
  readAsStringAsync: jest.fn(() => Promise.resolve()),
  writeAsStringAsync: jest.fn(() => Promise.resolve()),
  deleteAsync: jest.fn(() => Promise.resolve()),
  moveAsync: jest.fn(() => Promise.resolve()),
  copyAsync: jest.fn(() => Promise.resolve()),
  makeDirectoryAsync: jest.fn(() => Promise.resolve()),
  readDirectoryAsync: jest.fn(() => Promise.resolve()),
  createDownloadResumable: jest.fn(() => Promise.resolve()),
}));

jest.mock('react-native/Libraries/Image/AssetRegistry', () => ({
  registerAsset: jest.fn(() => 1),
  getAssetByID: jest.fn(() => ({
    fileSystemLocation: '/full/path/to/directory',
    httpServerLocation: '/assets/full/path/to/directory',
    scales: [1],
    fileHashes: ['md5'],
    name: 'name',
    exists: true,
    type: 'type',
    hash: 'md5',
    uri: 'uri',
    width: 1,
    height: 1,
  })),
}));

jest.mock('react-native-gesture-handler', () => {
  const View = require('react-native/Libraries/Components/View/View');
  return {
    Swipeable: View,
    DrawerLayout: View,
    State: {},
    ScrollView: View,
    Slider: View,
    Switch: View,
    TextInput: View,
    ToolbarAndroid: View,
    ViewPagerAndroid: View,
    DrawerLayoutAndroid: View,
    WebView: View,
    NativeViewGestureHandler: View,
    TapGestureHandler: View,
    FlingGestureHandler: View,
    ForceTouchGestureHandler: View,
    LongPressGestureHandler: View,
    PanGestureHandler: View,
    PinchGestureHandler: View,
    RotationGestureHandler: View,
    /* Buttons */
    RawButton: View,
    BaseButton: View,
    RectButton: View,
    BorderlessButton: View,
    /* Other */
    FlatList: View,
    gestureHandlerRootHOC: jest.fn(),
    Directions: {},
  };
});

jest.doMock('react-native/Libraries/BatchedBridge/NativeModules', () => mockNativeModules);

jest.mock('@unimodules/react-native-adapter', () => {
  const ReactNativeAdapter = require.requireActual('@unimodules/react-native-adapter');
  const { NativeModulesProxy } = ReactNativeAdapter;

  // After the NativeModules mock is set up, we can mock NativeModuleProxy's functions that call
  // into the native proxy module. We're not really interested in checking whether the underlying
  // method is called, just that the proxy method is called, since we have unit tests for the
  // adapter and believe it works correctly.
  //
  // NOTE: The adapter validates the number of arguments, which we don't do in the mocked functions.
  // This means the mock functions will not throw validation errors the way they would in an app.
  for (const moduleName of Object.keys(NativeModulesProxy)) {
    const nativeModule = NativeModulesProxy[moduleName];
    for (const propertyName of Object.keys(nativeModule)) {
      if (typeof nativeModule[propertyName] === 'function') {
        nativeModule[propertyName] = jest.fn(async () => {});
      }
    }
  }

  return ReactNativeAdapter;
});

// The UIManager module is not idempotent and causes issues if we load it again after resetting
// the modules with Jest.
let UIManager;
jest.doMock('react-native/Libraries/ReactNative/UIManager', () => {
  if (!UIManager) {
    UIManager = require.requireActual('react-native/Libraries/ReactNative/UIManager');
  }
  return UIManager;
});
<|endoftext|>


<commit_before>(function () {
    "use strict";
    /*global module*/

    const
        isWindows = (/^win/).test(process.platform),
        isMacOS = process.platform === "darwin";

    module.exports = {

        capitalize: function (string) {
            return string.charAt(0).toUpperCase() + string.substr(1);
        },

        isWindows: isWindows,
        isMacOS: isMacOS

    };

}());
<commit_msg>Fix linting issue<commit_after>(function () {
    "use strict";
    /*global module*/

    var isWindows = (/^win/).test(process.platform),
        isMacOS = process.platform === "darwin";

    module.exports = {

        capitalize: function (string) {
            return string.charAt(0).toUpperCase() + string.substr(1);
        },

        isWindows: isWindows,
        isMacOS: isMacOS

    };

}());
<|endoftext|>


<commit_before><commit_msg>use header organism on all routes and use new withNavigation decorator<commit_after><|endoftext|>