<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc service
     * @name requisition-non-full-supply.categoryFactory
     *
     * @description
     * Responsible for grouping products into categories to be displayed on the Add Product modal.
     */
    angular
        .module('report')
        .factory('reportFactory', factory);

    factory.$inject = ['$http', '$q', 'openlmisUrlFactory', 'reportService'];

    function factory($http, $q, openlmisUrlFactory, reportService) {
        var factory = {
            getReport: getReport,
            getReports: getReports,
            getAllReports: getAllReports,
            getReportParamsOptions: getReportParamsOptions
        };
        return factory;

        function getReport(module, id) {
            var deferred = $q.defer();

            reportService.getReport(module, id).then(function(report) {
                report.$module = module;
                deferred.resolve(report);
            }, deferred.reject);

            return deferred.promise;
        }

        function getReports(module) {
            var deferred = $q.defer();

            reportService.getReports(module).then(function(reports) {
                angular.forEach(reports, function(report) {
                    report.$module = module;
                });
                deferred.resolve(reports);
            }, deferred.reject);

            return deferred.promise;
        }

        function getAllReports() {
            var promises = [],
                deferred = $q.defer();

            angular.forEach(['requisitions'], function(module) {
                promises.push(getReports(module));
            });

            $q.all(promises).then(function(reportLists) {
                var allReports = [];

                angular.forEach(reportLists, function(reportList) {
                    allReports = allReports.concat(reportList);
                });

                deferred.resolve(allReports);
            }, deferred.reject);

            return deferred.promise;
        }

        function getReportParamsOptions(report) {
            var deferred = $q.defer(),
                promises = [],
                parameters = {};

            angular.forEach(report.templateParameters, function(param) {
                var paramDeferred = $q.defer();

                promises.push(paramDeferred.promise);

                getReportParamOptions(
                    param.selectExpression,
                    param.selectProperty,
                    param.displayProperty
                ).then(function(params) {
                    parameters[param.name] = params;
                    paramDeferred.resolve();
                }, paramDeferred.reject);
            });

            $q.all(promises).then(function() {
                deferred.resolve(parameters);
            }, deferred.reject);

            return deferred.promise;
        }

        function getReportParamOptions(uri, property, displayName) {
            var deferred = $q.defer();

            reportService.getReportParamsOptions(uri).then(function(response) {
                var items = [];

                // Support paginated endpoints
                var data = response.data;
                if (data.content && data.totalElements > 0) {
                  data = data.content;
                }

                angular.forEach(response.data, function(obj) {
                    var value = property ? obj[property] : obj;
                    var name = displayName ? obj[displayName] : value;

                    if (value) {
                        items.push({
                            'name': name,
                            'value': value
                        });
                    }
                });

                deferred.resolve(items);
            }, deferred.reject);

            return deferred.promise;
        }
    }

})();
<commit_msg>Fix retrieving paginated report parameters<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc service
     * @name requisition-non-full-supply.categoryFactory
     *
     * @description
     * Responsible for grouping products into categories to be displayed on the Add Product modal.
     */
    angular
        .module('report')
        .factory('reportFactory', factory);

    factory.$inject = ['$http', '$q', 'openlmisUrlFactory', 'reportService'];

    function factory($http, $q, openlmisUrlFactory, reportService) {
        var factory = {
            getReport: getReport,
            getReports: getReports,
            getAllReports: getAllReports,
            getReportParamsOptions: getReportParamsOptions
        };
        return factory;

        function getReport(module, id) {
            var deferred = $q.defer();

            reportService.getReport(module, id).then(function(report) {
                report.$module = module;
                deferred.resolve(report);
            }, deferred.reject);

            return deferred.promise;
        }

        function getReports(module) {
            var deferred = $q.defer();

            reportService.getReports(module).then(function(reports) {
                angular.forEach(reports, function(report) {
                    report.$module = module;
                });
                deferred.resolve(reports);
            }, deferred.reject);

            return deferred.promise;
        }

        function getAllReports() {
            var promises = [],
                deferred = $q.defer();

            angular.forEach(['requisitions'], function(module) {
                promises.push(getReports(module));
            });

            $q.all(promises).then(function(reportLists) {
                var allReports = [];

                angular.forEach(reportLists, function(reportList) {
                    allReports = allReports.concat(reportList);
                });

                deferred.resolve(allReports);
            }, deferred.reject);

            return deferred.promise;
        }

        function getReportParamsOptions(report) {
            var deferred = $q.defer(),
                promises = [],
                parameters = {};

            angular.forEach(report.templateParameters, function(param) {
                var paramDeferred = $q.defer();

                promises.push(paramDeferred.promise);

                getReportParamOptions(
                    param.selectExpression,
                    param.selectProperty,
                    param.displayProperty
                ).then(function(params) {
                    parameters[param.name] = params;
                    paramDeferred.resolve();
                }, paramDeferred.reject);
            });

            $q.all(promises).then(function() {
                deferred.resolve(parameters);
            }, deferred.reject);

            return deferred.promise;
        }

        function getReportParamOptions(uri, property, displayName) {
            var deferred = $q.defer();

            reportService.getReportParamsOptions(uri).then(function(response) {
                var items = [];

                // Support paginated endpoints
                var data = response.data;
                if (data.content && data.totalElements > 0) {
                  data = data.content;
                }

                angular.forEach(data, function(obj) {
                    var value = property ? obj[property] : obj;
                    var name = displayName ? obj[displayName] : value;

                    if (value) {
                        items.push({
                            'name': name,
                            'value': value
                        });
                    }
                });

                deferred.resolve(items);
            }, deferred.reject);

            return deferred.promise;
        }
    }

})();
<|endoftext|>


<commit_before>import parser from '../../parser';

export default function createCommand(cli, def) {
    if (!def.command) throw new Error('Property `command` not found in the command definition.');
    if (!def.handler) throw new Error('Property `handler` not found in the command definition.');
    if (!def.describe) throw new Error('Property `describe` not found in the command definition.');

    def.name = def.command.split(' ')[0].trim();
    if (def.name.length === 0) {
        throw new Error('Property `name` can\'t be defined.');
    }

    const userBuilder = def.builder || ((yargs) => yargs);
    def.builder = (yargs) => {
        yargs = userBuilder(yargs)
            .config()
            .pkgConf('chan', process.cwd());

        if (cli.commandsArgv && cli.commandsArgv[def.name]) {
            yargs.config(cli.commandsArgv[def.name]);
        }

        return yargs;
    };

    const userHandler = def.handler;
    def.handler = (argv) => {
        const parserInstance = parser(argv.path);
        parserInstance.gitCompare = argv.gitCompare;
        const result = userHandler.call(
            cli,
            parserInstance,
            argv,
            () => {
                return new Promise((resolve) => {
                    const data = parserInstance.stringify();
                    // write callback function
                    if (argv.stdout) {
                        process.stdout.write(data);
                    } else {
                        parserInstance.write(data);
                    }
                    resolve(data);
                });
            }
        );

        if (!result || typeof result.then !== 'function') {
            return new Promise((resolve) => {
                resolve();
            });
        }

        return result;
    };

    cli.yargs().command(def);

    return def;
}
<commit_msg>fix wording in Error message<commit_after>import parser from '../../parser';

export default function createCommand(cli, def) {
    if (!def.command) throw new Error('Property `command` not found in the command definition.');
    if (!def.handler) throw new Error('Property `handler` not found in the command definition.');
    if (!def.describe) throw new Error('Property `describe` not found in the command definition.');

    def.name = def.command.split(' ')[0].trim();
    if (def.name.length === 0) {
        throw new Error('Property `name` must be defined.');
    }

    const userBuilder = def.builder || ((yargs) => yargs);
    def.builder = (yargs) => {
        yargs = userBuilder(yargs)
            .config()
            .pkgConf('chan', process.cwd());

        if (cli.commandsArgv && cli.commandsArgv[def.name]) {
            yargs.config(cli.commandsArgv[def.name]);
        }

        return yargs;
    };

    const userHandler = def.handler;
    def.handler = (argv) => {
        const parserInstance = parser(argv.path);
        parserInstance.gitCompare = argv.gitCompare;
        const result = userHandler.call(
            cli,
            parserInstance,
            argv,
            () => {
                return new Promise((resolve) => {
                    const data = parserInstance.stringify();
                    // write callback function
                    if (argv.stdout) {
                        process.stdout.write(data);
                    } else {
                        parserInstance.write(data);
                    }
                    resolve(data);
                });
            }
        );

        if (!result || typeof result.then !== 'function') {
            return new Promise((resolve) => {
                resolve();
            });
        }

        return result;
    };

    cli.yargs().command(def);

    return def;
}
<|endoftext|>


<commit_before>'use strict';

//var Version="0.3";

var app = angular.module('WebFormApp', ['pascalprecht.translate']);
app.controller('WebFormAppCtrl', ['$eea', '$scope', '$http', '$timeout', '$window', '$translate', '$compile', WebFormAppCtrl]);

/**
* WebFormAppCtrl: Main controller
*/
function WebFormAppCtrl($eea, $scope) {

	$eea.init($scope);

	//examples - active js rest

	// js libraries
	//$eea.libraries.$.2.2
	//$eea.libraries.angular.1.6

	//$eea.data.destinations.json

	$scope.save = function () {
		$eea.form.save($scope);
	};

	$scope.submit = function (frm, test) {
		return $eea.form.submit(frm, test, $scope);
	};

	$scope.addRow = function (frm, group) {
		$eea.group.addRow(frm, group, $scope);
	};

	$scope.deleteRow = function (frm, group, id) {
		$eea.group.deleteRow(frm, group, id, $scope);
	};
}

eea.services.get("eeawebformcore");
eea.components.getAll([
	"eeaheader",
	"eeamenu",
	"eeafooter",
	"eeaformtesting",
	"eealanguage",
	"eeatoolbar",
	"eealookup",
	"eeaformviewmode",
	"eeaformvalidation",
	"eeabuildinfo"
]);
eea.css.get("webform.all");

/*
TODO
- Error Reporting/Form Deactivating Component
- Lookup Component. AutoGrouping in case more than once instances have the same attributes
- Lookup Component. When adding row, get data from existing instance)

TOTEST
Enviromental Computing and Networking

 Try dynamic loading in object - chain

 // Use remote libraries and functions or get data instantly
 eea.greece.athens.chalandri.getSomething()
 eea.italy.rome.somewhere.getSomethingElse()

 // Travel guide
 eea.italy.rome.somearea.tourism.list()

 // Shopping guide - get area shops
 eea.italy.rome.somearea.shopping.list()
 eea.italy.rome.somearea.shopping.shop1.listProducts()

 // Telephone system via internet
 // No cables and satelites
 call $1.$2.$8.$3.ring()

 // Check available public functionality - old BBS style
 eea.denmark.eea.getFunctionList()
 // Use the listed functionality
 // Local tv streaming - no atmosphere antenna transmissions and satelites
 eea.denmark.eea.streamChannel(120)
 // Video Conference Channel
 eea.denmark.eea.joinVideoConference("test")
 // Connect your iot sensor
 eea.iot.api.client.connect()

	[eea root library] <--- bind library test eea.test (no downtime)
				 ^
				 |
				 /\
				/  \
   dynamic lib 1 eea.test.area1      dynamic lib 2 <-- eea.test.area2
		      				 ^
						 |
						 /\
						/  \
					eea.test.area2.iot
	eea.test.area2.iot.device1.getData() 	   eea.test.area2.iot.device2.getData()

CANNOTTEST

Quantum spooky phenomenon
parallel interacted particles to digital
Example:
128 one side <--> 128 interacted other side

*/
<commit_msg>Updated TODO in webform.js<commit_after>'use strict';

//var Version="0.3";

var app = angular.module('WebFormApp', ['pascalprecht.translate']);
app.controller('WebFormAppCtrl', ['$eea', '$scope', '$http', '$timeout', '$window', '$translate', '$compile', WebFormAppCtrl]);

/**
* WebFormAppCtrl: Main controller
*/
function WebFormAppCtrl($eea, $scope) {

	$eea.init($scope);

	//examples - active js rest

	// js libraries
	//$eea.libraries.$.2.2
	//$eea.libraries.angular.1.6

	//$eea.data.destinations.json

	$scope.save = function () {
		$eea.form.save($scope);
	};

	$scope.submit = function (frm, test) {
		return $eea.form.submit(frm, test, $scope);
	};

	$scope.addRow = function (frm, group) {
		$eea.group.addRow(frm, group, $scope);
	};

	$scope.deleteRow = function (frm, group, id) {
		$eea.group.deleteRow(frm, group, id, $scope);
	};
}

eea.services.get("eeawebformcore");
eea.components.getAll([
	"eeaheader",
	"eeamenu",
	"eeafooter",
	"eeaformtesting",
	"eealanguage",
	"eeatoolbar",
	"eealookup",
	"eeaformviewmode",
	"eeaformvalidation",
	"eeabuildinfo"
]);
eea.css.get("webform.all");

/*
TODO
- Error Reporting/Form Deactivating Component
- Lookup Component. AutoGrouping in case more than once instances have the same attributes
- Lookup Component. When adding row, get data from existing instance

TOTEST
Enviromental Computing and Networking

 Try dynamic loading in object - chain

 // Use remote libraries and functions or get data instantly
 eea.greece.athens.chalandri.getSomething()
 eea.italy.rome.somewhere.getSomethingElse()

 // Travel guide
 eea.italy.rome.somearea.tourism.list()

 // Shopping guide - get area shops
 eea.italy.rome.somearea.shopping.list()
 eea.italy.rome.somearea.shopping.shop1.listProducts()

 // Telephone system via internet
 // No cables and satelites
 call $1.$2.$8.$3.ring()

 // Check available public functionality - old BBS style
 eea.denmark.eea.getFunctionList()
 // Use the listed functionality
 // Local tv streaming - no atmosphere antenna transmissions and satelites
 eea.denmark.eea.streamChannel(120)
 // Video Conference Channel
 eea.denmark.eea.joinVideoConference("test")
 // Connect your iot sensor
 eea.iot.api.client.connect()

	[eea root library] <--- bind library test eea.test (no downtime)
				 ^
				 |
				 /\
				/  \
   dynamic lib 1 eea.test.area1      dynamic lib 2 <-- eea.test.area2
		      				 ^
						 |
						 /\
						/  \
					eea.test.area2.iot
	eea.test.area2.iot.device1.getData() 	   eea.test.area2.iot.device2.getData()

CANNOTTEST

Quantum spooky phenomenon
parallel interacted particles to digital
Example:
128 one side <--> 128 interacted other side

*/
<|endoftext|>


<commit_before><commit_msg>Rellocate dataview errors<commit_after><|endoftext|>


<commit_before>import Promise from 'es6-promise';
import { NotFoundError, isDefined } from 'kinvey-js-sdk/dist/export';
import keyBy from 'lodash/keyBy';
import merge from 'lodash/merge';
import values from 'lodash/values';
import forEach from 'lodash/forEach';
import find from 'lodash/find';

const idAttribute = process.env.KINVEY_ID_ATTRIBUTE || '_id';
const masterCollectionName = 'master';

export class WebStorageAdapter {
  constructor(name = 'kinvey') {
    this.name = name;
  }

  get masterCollectionName() {
    return `${this.name}${masterCollectionName}`;
  }
}

export class LocalStorageAdapter extends WebStorageAdapter {
  constructor(name) {
    super(name);

    const masterCollection = global.localStorage.getItem(this.masterCollectionName);
    if (isDefined(masterCollection) === false) {
      global.localStorage.setItem(this.masterCollectionName, JSON.stringify([]));
    }
  }

  _find(collection) {
    try {
      const entities = global.localStorage.getItem(collection);

      if (isDefined(entities)) {
        return Promise.resolve(JSON.parse(entities));
      }

      return Promise.resolve(entities || []);
    } catch (error) {
      return Promise.reject(error);
    }
  }

  find(collection) {
    return this._find(`${this.name}${collection}`);
  }

  findById(collection, id) {
    return this.find(collection)
      .then((entities) => {
        const entity = find(entities, entity => entity[idAttribute] === id);

        if (isDefined(entity) === false) {
          throw new NotFoundError(`An entity with _id = ${id} was not found in the ${collection}`
            + ` collection on the ${this.name} localstorage database.`);
        }

        return entity;
      });
  }

  save(collection, entities) {
    return this._find(this.masterCollectionName)
      .then((collections) => {
        if (collections.indexOf(collection) === -1) {
          collections.push(collection);
          global.localStorage.setItem(this.masterCollectionName, JSON.stringify(collections));
        }

        return this.find(collection);
      })
      .then((existingEntities) => {
        const existingEntitiesById = keyBy(existingEntities, idAttribute);
        const entitiesById = keyBy(entities, idAttribute);
        const existingEntityIds = Object.keys(existingEntitiesById);

        forEach(existingEntityIds, (id) => {
          const existingEntity = existingEntitiesById[id];
          const entity = entitiesById[id];

          if (isDefined(entity)) {
            entitiesById[id] = merge(existingEntity, entity);
          } else {
            entitiesById[id] = existingEntity;
          }
        });

        global.localStorage.setItem(`${this.name}${collection}`, JSON.stringify(values(entitiesById)));
        return entities;
      });
  }

  removeById(collection, id) {
    return this.find(collection)
      .then((entities) => {
        const entitiesById = keyBy(entities, idAttribute);
        const entity = entitiesById[id];

        if (isDefined(entity) === false) {
          throw new NotFoundError(`An entity with _id = ${id} was not found in the ${collection} ` +
            `collection on the ${this.name} memory database.`);
        }

        delete entitiesById[id];
        return this.save(collection, values(entitiesById))
          .then(() => ({ count: 1 }));
      });
  }

  clear() {
    return this._find(this.masterCollectionName)
      .then((collections) => {
        forEach(collections, (collection) => {
          global.localStorage.removeItem(`${this.name}${collection}`);
        });

        global.localStorage.removeItem(this.masterCollectionName);
        return null;
      });
  }

  static load(name) {
    if (isDefined(global.localStorage)) {
      const item = '__testSupport';
      try {
        global.localStorage.setItem(item, item);
        global.localStorage.getItem(item);
        global.localStorage.removeItem(item);
        return Promise.resolve(new LocalStorageAdapter(name));
      } catch (e) {
        return Promise.resolve(undefined);
      }
    }

    return Promise.resolve(undefined);
  }
}

export class SessionStorageAdapter extends WebStorageAdapter {
  constructor(name) {
    super(name);

    const masterCollection = global.sessionStorage.getItem(this.masterCollectionName);
    if (isDefined(masterCollection) === false) {
      global.sessionStorage.setItem(this.masterCollectionName, JSON.stringify([]));
    }
  }

  _find(collection) {
    try {
      const entities = global.sessionStorage.getItem(collection);

      if (isDefined(entities)) {
        return Promise.resolve(JSON.parse(entities));
      }

      return Promise.resolve(entities || []);
    } catch (error) {
      return Promise.reject(error);
    }
  }

  find(collection) {
    return this._find(`${this.name}${collection}`);
  }

  findById(collection, id) {
    return this.find(collection)
      .then((entities) => {
        const entity = find(entities, entity => entity[idAttribute] === id);

        if (isDefined(entity) === false) {
          throw new NotFoundError(`An entity with _id = ${id} was not found in the ${collection}`
            + ` collection on the ${this.name} localstorage database.`);
        }

        return entity;
      });
  }

  save(collection, entities) {
    return this._find(this.masterCollectionName)
      .then((collections) => {
        if (collections.indexOf(collection) === -1) {
          collections.push(collection);
          global.sessionStorage.setItem(this.masterCollectionName, JSON.stringify(collections));
        }

        return this.find(collection);
      })
      .then((existingEntities) => {
        const existingEntitiesById = keyBy(existingEntities, idAttribute);
        const entitiesById = keyBy(entities, idAttribute);
        const existingEntityIds = Object.keys(existingEntitiesById);

        forEach(existingEntityIds, (id) => {
          const existingEntity = existingEntitiesById[id];
          const entity = entitiesById[id];

          if (isDefined(entity)) {
            entitiesById[id] = merge(existingEntity, entity);
          } else {
            entitiesById[id] = existingEntity;
          }
        });

        global.sessionStorage.setItem(`${this.name}${collection}`, JSON.stringify(values(entitiesById)));
        return entities;
      });
  }

  removeById(collection, id) {
    return this.find(collection)
      .then((entities) => {
        const entitiesById = keyBy(entities, idAttribute);
        const entity = entitiesById[id];

        if (isDefined(entity) === false) {
          throw new NotFoundError(`An entity with _id = ${id} was not found in the ${collection} ` +
            `collection on the ${this.name} memory database.`);
        }

        delete entitiesById[id];
        return this.save(collection, values(entitiesById))
          .then(() => ({ count: 1 }));
      });
  }

  clear() {
    return this._find(this.masterCollectionName)
      .then((collections) => {
        forEach(collections, (collection) => {
          global.sessionStorage.removeItem(`${this.name}${collection}`);
        });

        global.sessionStorage.removeItem(this.masterCollectionName);
        return null;
      });
  }

  static load(name) {
    if (global.sessionStorage) {
      const item = '__testSupport';
      try {
        global.sessionStorage.setItem(item, item);
        global.sessionStorage.getItem(item);
        global.sessionStorage.removeItem(item);
        return Promise.resolve(new SessionStorageAdapter(name));
      } catch (e) {
        return Promise.resolve(undefined);
      }
    }

    return Promise.resolve(undefined);
  }
}

export class CookieStorageAdapter extends WebStorageAdapter {
  constructor(name) {
    super(name);

    const values = document.cookie.split(';');
    for (let i = 0, len = values.length; i < len; i += 1) {
      let value = values[i];
      while (value.charAt(0) === ' ') {
        value = value.substring(1);
      }
      if (value.indexOf(this.masterCollectionName) === 0) {
        const masterCollection = decodeURIComponent(value.substring(this.masterCollectionName.length, value.length));

        if (isDefined(masterCollection) === false) {
          const expires = new Date();
          expires.setTime(expires.getTime() + (100 * 365 * 24 * 60 * 60 * 1000)); // Expire in 100 years
          global.document.cookie = `${this.masterCollectionName}=${encodeURIComponent(JSON.stringify([]))}; expires=${expires.toUTCString()}; path=/`;
        }
      }
    }
  }

  _find(collection) {
    const values = document.cookie.split(';');
    for (let i = 0, len = values.length; i < len; i += 1) {
      let value = values[i];
      while (value.charAt(0) === ' ') {
        value = value.substring(1);
      }
      if (value.indexOf(collection) === 0) {
        return Promise.resolve(JSON.parse(decodeURIComponent(value.substring(collection.length, value.length))));
      }
    }
    return Promise.resolve([]);
  }

  find(collection) {
    return this._find(`${this.name}${collection}`);
  }

  findById(collection, id) {
    return this.find(collection)
      .then((entities) => {
        const entity = find(entities, entity => entity[idAttribute] === id);

        if (isDefined(entity) === false) {
          throw new NotFoundError(`An entity with _id = ${id} was not found in the ${collection}`
            + ` collection on the ${this.name} localstorage database.`);
        }

        return entity;
      });
  }

  save(collection, entities) {
    return this._find(this.masterCollectionName)
      .then((collections) => {
        if (collections.indexOf(collection) === -1) {
          collections.push(collection);
          const expires = new Date();
          expires.setTime(expires.getTime() + (100 * 365 * 24 * 60 * 60 * 1000)); // Expire in 100 years
          global.document.cookie = `${this.masterCollectionName}=${encodeURIComponent(JSON.stringify(collections))}; expires=${expires.toUTCString()}; path=/`;
        }

        return this.find(collection);
      })
      .then((existingEntities) => {
        const existingEntitiesById = keyBy(existingEntities, idAttribute);
        const existingEntityIds = Object.keys(existingEntitiesById);
        const entitiesById = keyBy(entities, idAttribute);

        forEach(existingEntityIds, (id) => {
          const existingEntity = existingEntitiesById[id];
          const entity = entitiesById[id];

          if (isDefined(entity)) {
            entitiesById[id] = merge(existingEntity, entity);
          } else {
            entitiesById[id] = existingEntity;
          }
        });

        const expires = new Date();
        expires.setTime(expires.getTime() + (100 * 365 * 24 * 60 * 60 * 1000)); // Expire in 100 years
        global.document.cookie = `${this.name}${collection}=${encodeURIComponent(JSON.stringify(values(entitiesById)))}; expires=${expires.toUTCString()}; path=/`;
        return entities;
      });
  }

  removeById(collection, id) {
    return this.find(collection)
      .then((entities) => {
        const entitiesById = keyBy(entities, idAttribute);
        const entity = entitiesById[id];

        if (isDefined(entity) === false) {
          throw new NotFoundError(`An entity with _id = ${id} was not found in the ${collection} ` +
            `collection on the ${this.name} memory database.`);
        }

        delete entitiesById[id];
        return this.save(collection, values(entitiesById))
          .then(() => ({ count: 1 }));
      });
  }

  clear() {
    return this._find(this.masterCollectionName)
      .then((collections) => {
        forEach(collections, (collection) => {
          const expires = new Date();
          expires.setTime(expires.getTime() + (100 * 365 * 24 * 60 * 60 * 1000)); // Expire in 100 years
          global.document.cookie = `${this.name}${collection}=${encodeURIComponent()}; expires=${expires.toUTCString()}; path=/`;
        });

        const expires = new Date();
        expires.setTime(expires.getTime() + (100 * 365 * 24 * 60 * 60 * 1000)); // Expire in 100 years
        global.document.cookie = `${this.masterCollectionName}=${encodeURIComponent()}; expires=${expires.toUTCString()}; path=/`;
        return null;
      });
  }

  static load(name) {
    if (typeof global.document.cookie === 'undefined') {
      return Promise.resolve(undefined);
    }

    return Promise.resolve(new CookieStorageAdapter(name));
  }
}
<commit_msg>Fix removeById() for web storage adapters<commit_after>import Promise from 'es6-promise';
import { NotFoundError, isDefined } from 'kinvey-js-sdk/dist/export';
import keyBy from 'lodash/keyBy';
import merge from 'lodash/merge';
import values from 'lodash/values';
import forEach from 'lodash/forEach';
import find from 'lodash/find';

const idAttribute = process.env.KINVEY_ID_ATTRIBUTE || '_id';
const masterCollectionName = 'master';

export class WebStorageAdapter {
  constructor(name = 'kinvey') {
    this.name = name;
  }

  get masterCollectionName() {
    return `${this.name}${masterCollectionName}`;
  }
}

export class LocalStorageAdapter extends WebStorageAdapter {
  constructor(name) {
    super(name);

    const masterCollection = global.localStorage.getItem(this.masterCollectionName);
    if (isDefined(masterCollection) === false) {
      global.localStorage.setItem(this.masterCollectionName, JSON.stringify([]));
    }
  }

  _find(collection) {
    try {
      const entities = global.localStorage.getItem(collection);

      if (isDefined(entities)) {
        return Promise.resolve(JSON.parse(entities));
      }

      return Promise.resolve(entities || []);
    } catch (error) {
      return Promise.reject(error);
    }
  }

  find(collection) {
    return this._find(`${this.name}${collection}`);
  }

  findById(collection, id) {
    return this.find(collection)
      .then((entities) => {
        const entity = find(entities, entity => entity[idAttribute] === id);

        if (isDefined(entity) === false) {
          throw new NotFoundError(`An entity with _id = ${id} was not found in the ${collection}`
            + ` collection on the ${this.name} localstorage database.`);
        }

        return entity;
      });
  }

  save(collection, entities) {
    return this._find(this.masterCollectionName)
      .then((collections) => {
        if (collections.indexOf(collection) === -1) {
          collections.push(collection);
          global.localStorage.setItem(this.masterCollectionName, JSON.stringify(collections));
        }

        return this.find(collection);
      })
      .then((existingEntities) => {
        const existingEntitiesById = keyBy(existingEntities, idAttribute);
        const entitiesById = keyBy(entities, idAttribute);
        const existingEntityIds = Object.keys(existingEntitiesById);

        forEach(existingEntityIds, (id) => {
          const existingEntity = existingEntitiesById[id];
          const entity = entitiesById[id];

          if (isDefined(entity)) {
            entitiesById[id] = merge(existingEntity, entity);
          } else {
            entitiesById[id] = existingEntity;
          }
        });

        global.localStorage.setItem(`${this.name}${collection}`, JSON.stringify(values(entitiesById)));
        return entities;
      });
  }

  removeById(collection, id) {
    return this.find(collection)
      .then((entities) => {
        const entitiesById = keyBy(entities, idAttribute);
        const entity = entitiesById[id];

        if (isDefined(entity) === false) {
          throw new NotFoundError(`An entity with _id = ${id} was not found in the ${collection} ` +
            `collection on the ${this.name} memory database.`);
        }

        delete entitiesById[id];
        global.localStorage.setItem(`${this.name}${collection}`, JSON.stringify(values(entitiesById)));
        return { count: 1 };
      });
  }

  clear() {
    return this._find(this.masterCollectionName)
      .then((collections) => {
        forEach(collections, (collection) => {
          global.localStorage.removeItem(`${this.name}${collection}`);
        });

        global.localStorage.removeItem(this.masterCollectionName);
        return null;
      });
  }

  static load(name) {
    if (isDefined(global.localStorage)) {
      const item = '__testSupport';
      try {
        global.localStorage.setItem(item, item);
        global.localStorage.getItem(item);
        global.localStorage.removeItem(item);
        return Promise.resolve(new LocalStorageAdapter(name));
      } catch (e) {
        return Promise.resolve(undefined);
      }
    }

    return Promise.resolve(undefined);
  }
}

export class SessionStorageAdapter extends WebStorageAdapter {
  constructor(name) {
    super(name);

    const masterCollection = global.sessionStorage.getItem(this.masterCollectionName);
    if (isDefined(masterCollection) === false) {
      global.sessionStorage.setItem(this.masterCollectionName, JSON.stringify([]));
    }
  }

  _find(collection) {
    try {
      const entities = global.sessionStorage.getItem(collection);

      if (isDefined(entities)) {
        return Promise.resolve(JSON.parse(entities));
      }

      return Promise.resolve(entities || []);
    } catch (error) {
      return Promise.reject(error);
    }
  }

  find(collection) {
    return this._find(`${this.name}${collection}`);
  }

  findById(collection, id) {
    return this.find(collection)
      .then((entities) => {
        const entity = find(entities, entity => entity[idAttribute] === id);

        if (isDefined(entity) === false) {
          throw new NotFoundError(`An entity with _id = ${id} was not found in the ${collection}`
            + ` collection on the ${this.name} localstorage database.`);
        }

        return entity;
      });
  }

  save(collection, entities) {
    return this._find(this.masterCollectionName)
      .then((collections) => {
        if (collections.indexOf(collection) === -1) {
          collections.push(collection);
          global.sessionStorage.setItem(this.masterCollectionName, JSON.stringify(collections));
        }

        return this.find(collection);
      })
      .then((existingEntities) => {
        const existingEntitiesById = keyBy(existingEntities, idAttribute);
        const entitiesById = keyBy(entities, idAttribute);
        const existingEntityIds = Object.keys(existingEntitiesById);

        forEach(existingEntityIds, (id) => {
          const existingEntity = existingEntitiesById[id];
          const entity = entitiesById[id];

          if (isDefined(entity)) {
            entitiesById[id] = merge(existingEntity, entity);
          } else {
            entitiesById[id] = existingEntity;
          }
        });

        global.sessionStorage.setItem(`${this.name}${collection}`, JSON.stringify(values(entitiesById)));
        return entities;
      });
  }

  removeById(collection, id) {
    return this.find(collection)
      .then((entities) => {
        const entitiesById = keyBy(entities, idAttribute);
        const entity = entitiesById[id];

        if (isDefined(entity) === false) {
          throw new NotFoundError(`An entity with _id = ${id} was not found in the ${collection} ` +
            `collection on the ${this.name} memory database.`);
        }

        delete entitiesById[id];
        global.sessionStorage.setItem(`${this.name}${collection}`, JSON.stringify(values(entitiesById)));
        return { count: 1 };
      });
  }

  clear() {
    return this._find(this.masterCollectionName)
      .then((collections) => {
        forEach(collections, (collection) => {
          global.sessionStorage.removeItem(`${this.name}${collection}`);
        });

        global.sessionStorage.removeItem(this.masterCollectionName);
        return null;
      });
  }

  static load(name) {
    if (global.sessionStorage) {
      const item = '__testSupport';
      try {
        global.sessionStorage.setItem(item, item);
        global.sessionStorage.getItem(item);
        global.sessionStorage.removeItem(item);
        return Promise.resolve(new SessionStorageAdapter(name));
      } catch (e) {
        return Promise.resolve(undefined);
      }
    }

    return Promise.resolve(undefined);
  }
}

export class CookieStorageAdapter extends WebStorageAdapter {
  constructor(name) {
    super(name);

    const values = global.document.cookie.split(';');
    for (let i = 0, len = values.length; i < len; i += 1) {
      let value = values[i];
      while (value.charAt(0) === ' ') {
        value = value.substring(1);
      }
      if (value.indexOf(this.masterCollectionName) === 0) {
        const masterCollection = decodeURIComponent(value.substring(this.masterCollectionName.length, value.length));

        if (isDefined(masterCollection) === false) {
          const expires = new Date();
          expires.setTime(expires.getTime() + (100 * 365 * 24 * 60 * 60 * 1000)); // Expire in 100 years
          global.document.cookie = `${this.masterCollectionName}=${encodeURIComponent(JSON.stringify([]))}; expires=${expires.toUTCString()}; path=/`;
        }
      }
    }
  }

  _find(collection) {
    const values = global.document.cookie.split(';');
    for (let i = 0, len = values.length; i < len; i += 1) {
      let value = values[i];
      while (value.charAt(0) === ' ') {
        value = value.substring(1);
      }
      if (value.indexOf(collection) === 0) {
        return Promise.resolve(JSON.parse(decodeURIComponent(value.substring(collection.length + 1, value.length))));
      }
    }
    return Promise.resolve([]);
  }

  find(collection) {
    return this._find(`${this.name}${collection}`);
  }

  findById(collection, id) {
    return this.find(collection)
      .then((entities) => {
        const entity = find(entities, entity => entity[idAttribute] === id);

        if (isDefined(entity) === false) {
          throw new NotFoundError(`An entity with _id = ${id} was not found in the ${collection}`
            + ` collection on the ${this.name} localstorage database.`);
        }

        return entity;
      });
  }

  save(collection, entities) {
    return this._find(this.masterCollectionName)
      .then((collections) => {
        if (collections.indexOf(collection) === -1) {
          collections.push(collection);
          const expires = new Date();
          expires.setTime(expires.getTime() + (100 * 365 * 24 * 60 * 60 * 1000)); // Expire in 100 years
          global.document.cookie = `${this.masterCollectionName}=${encodeURIComponent(JSON.stringify(collections))}; expires=${expires.toUTCString()}; path=/`;
        }

        return this.find(collection);
      })
      .then((existingEntities) => {
        const existingEntitiesById = keyBy(existingEntities, idAttribute);
        const existingEntityIds = Object.keys(existingEntitiesById);
        const entitiesById = keyBy(entities, idAttribute);

        forEach(existingEntityIds, (id) => {
          const existingEntity = existingEntitiesById[id];
          const entity = entitiesById[id];

          if (isDefined(entity)) {
            entitiesById[id] = merge(existingEntity, entity);
          } else {
            entitiesById[id] = existingEntity;
          }
        });

        const expires = new Date();
        expires.setTime(expires.getTime() + (100 * 365 * 24 * 60 * 60 * 1000)); // Expire in 100 years
        global.document.cookie = `${this.name}${collection}=${encodeURIComponent(JSON.stringify(values(entitiesById)))}; expires=${expires.toUTCString()}; path=/`;
        return entities;
      });
  }

  removeById(collection, id) {
    return this.find(collection)
      .then((entities) => {
        const entitiesById = keyBy(entities, idAttribute);
        const entity = entitiesById[id];

        if (isDefined(entity) === false) {
          throw new NotFoundError(`An entity with _id = ${id} was not found in the ${collection} ` +
            `collection on the ${this.name} memory database.`);
        }

        delete entitiesById[id];
        const expires = new Date();
        expires.setTime(expires.getTime() + (100 * 365 * 24 * 60 * 60 * 1000)); // Expire in 100 years
        global.document.cookie = `${this.name}${collection}=${encodeURIComponent(JSON.stringify(values(entitiesById)))}; expires=${expires.toUTCString()}; path=/`;
        return { count: 1 };
      });
  }

  clear() {
    return this._find(this.masterCollectionName)
      .then((collections) => {
        forEach(collections, (collection) => {
          const expires = new Date();
          expires.setTime(expires.getTime() + (100 * 365 * 24 * 60 * 60 * 1000)); // Expire in 100 years
          global.document.cookie = `${this.name}${collection}=${encodeURIComponent(JSON.stringify([]))}; expires=${expires.toUTCString()}; path=/`;
        });

        const expires = new Date();
        expires.setTime(expires.getTime() + (100 * 365 * 24 * 60 * 60 * 1000)); // Expire in 100 years
        global.document.cookie = `${this.masterCollectionName}=${encodeURIComponent(JSON.stringify([]))}; expires=${expires.toUTCString()}; path=/`;
        return null;
      });
  }

  static load(name) {
    if (typeof global.document.cookie === 'undefined') {
      return Promise.resolve(undefined);
    }

    return Promise.resolve(new CookieStorageAdapter(name));
  }
}
<|endoftext|>


<commit_before>fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {

  /**
   * Populates canvas with data from the specified dataless JSON
   * JSON format must conform to the one of `fabric.Canvas#toDatalessJSON`
   * @deprecated since 1.2.2
   * @param {String|Object} json JSON string or object
   * @param {Function} callback Callback, invoked when json is parsed
   *                            and corresponding objects (e.g: fabric.Image)
   *                            are initialized
   * @return {fabric.Canvas} instance
   * @chainable
   */
  loadFromDatalessJSON: function (json, callback) {
    return this.loadFromJSON(json, callback);
  },

  /**
   * Populates canvas with data from the specified JSON
   * JSON format must conform to the one of `fabric.Canvas#toJSON`
   * @param {String|Object} json JSON string or object
   * @param {Function} callback Callback, invoked when json is parsed
   *                            and corresponding objects (e.g: fabric.Image)
   *                            are initialized
   * @return {fabric.Canvas} instance
   * @chainable
   */
  loadFromJSON: function (json, callback) {
    if (!json) return;

    // serialize if it wasn't already
    var serialized = (typeof json === 'string')
      ? JSON.parse(json)
      : json;

    this.clear();

    var _this = this;
    this._enlivenObjects(serialized.objects, function () {
      _this._setBgOverlayImages(serialized, callback);
    });

    return this;
  },

  _setBgOverlayImages: function(serialized, callback) {

    var _this = this,
        backgroundPatternLoaded,
        backgroundImageLoaded,
        overlayImageLoaded;

    var cbIfLoaded = function () {
      callback && backgroundImageLoaded && overlayImageLoaded && backgroundPatternLoaded && callback();
    };

    if (serialized.backgroundImage) {
      this.setBackgroundImage(serialized.backgroundImage, function() {

        _this.backgroundImageOpacity = serialized.backgroundImageOpacity;
        _this.backgroundImageStretch = serialized.backgroundImageStretch;

        _this.renderAll();

        backgroundImageLoaded = true;

        cbIfLoaded();
      });
    }
    else {
      backgroundImageLoaded = true;
    }

    if (serialized.overlayImage) {
      this.setOverlayImage(serialized.overlayImage, function() {

        _this.overlayImageLeft = serialized.overlayImageLeft || 0;
        _this.overlayImageTop = serialized.overlayImageTop || 0;

        _this.renderAll();
        overlayImageLoaded = true;

        cbIfLoaded();
      });
    }
    else {
      overlayImageLoaded = true;
    }

    if (serialized.background) {
      this.setBackgroundColor(serialized.background, function() {

        _this.renderAll();
        backgroundPatternLoaded = true;

        cbIfLoaded();
      });
    }
    else {
      backgroundPatternLoaded = true;
    }

    if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background) {
      callback && callback();
    }
  },

  /**
   * @private
   * @param {Array} objects
   * @param {Function} callback
   */
  _enlivenObjects: function (objects, callback) {
    var _this = this;
    if (objects.length === 0) {
      callback && callback();
    }
    fabric.util.enlivenObjects(objects, function(enlivenedObjects) {
      enlivenedObjects.forEach(function(obj, index) {
        _this.insertAt(obj, index, true);
        obj.setCoords();
      });
      callback && callback();
    });
  },

  /**
   * @private
   * @param {String} format
   * @param {Function} callback
   */
  _toDataURL: function (format, callback) {
    this.clone(function (clone) {
      callback(clone.toDataURL(format));
    });
  },

  /**
   * @private
   * @param {String} format
   * @param {Number} multiplier
   * @param {Function} callback
   */
  _toDataURLWithMultiplier: function (format, multiplier, callback) {
    this.clone(function (clone) {
      callback(clone.toDataURLWithMultiplier(format, multiplier));
    });
  },

  /**
   * Clones canvas instance
   * @param {Object} [callback] Receives cloned instance as a first argument
   */
  clone: function (callback) {
    var data = JSON.stringify(this);
    this.cloneWithoutData(function(clone) {
      clone.loadFromJSON(data, function() {
        callback && callback(clone);
      });
    });
  },

  /**
   * Clones canvas instance without cloning existing data.
   * This essentially copies canvas dimensions, clipping properties, etc.
   * but leaves data empty (so that you can populate it with your own)
   * @param {Object} [callback] Receives cloned instance as a first argument
   */
  cloneWithoutData: function(callback) {
    var el = fabric.document.createElement('canvas');

    el.width = this.getWidth();
    el.height = this.getHeight();

    var clone = new fabric.Canvas(el);
    clone.clipTo = this.clipTo;
    if (this.backgroundImage) {
      clone.setBackgroundImage(this.backgroundImage.src, function() {
        clone.renderAll();
        callback && callback(clone);
      });
      clone.backgroundImageOpacity = this.backgroundImageOpacity;
      clone.backgroundImageStretch = this.backgroundImageStretch;
    }
    else {
      callback && callback(clone);
    }
  }
});
<commit_msg>Avoid canvas re-rendering for each object when loading from JSON<commit_after>fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {

  /**
   * Populates canvas with data from the specified dataless JSON
   * JSON format must conform to the one of `fabric.Canvas#toDatalessJSON`
   * @deprecated since 1.2.2
   * @param {String|Object} json JSON string or object
   * @param {Function} callback Callback, invoked when json is parsed
   *                            and corresponding objects (e.g: fabric.Image)
   *                            are initialized
   * @return {fabric.Canvas} instance
   * @chainable
   */
  loadFromDatalessJSON: function (json, callback) {
    return this.loadFromJSON(json, callback);
  },

  /**
   * Populates canvas with data from the specified JSON
   * JSON format must conform to the one of `fabric.Canvas#toJSON`
   * @param {String|Object} json JSON string or object
   * @param {Function} callback Callback, invoked when json is parsed
   *                            and corresponding objects (e.g: fabric.Image)
   *                            are initialized
   * @return {fabric.Canvas} instance
   * @chainable
   */
  loadFromJSON: function (json, callback) {
    if (!json) return;

    // serialize if it wasn't already
    var serialized = (typeof json === 'string')
      ? JSON.parse(json)
      : json;

    this.clear();

    var _this = this;
    this._enlivenObjects(serialized.objects, function () {
      _this._setBgOverlayImages(serialized, callback);
    });

    return this;
  },

  _setBgOverlayImages: function(serialized, callback) {

    var _this = this,
        backgroundPatternLoaded,
        backgroundImageLoaded,
        overlayImageLoaded;

    var cbIfLoaded = function () {
      callback && backgroundImageLoaded && overlayImageLoaded && backgroundPatternLoaded && callback();
    };

    if (serialized.backgroundImage) {
      this.setBackgroundImage(serialized.backgroundImage, function() {

        _this.backgroundImageOpacity = serialized.backgroundImageOpacity;
        _this.backgroundImageStretch = serialized.backgroundImageStretch;

        _this.renderAll();

        backgroundImageLoaded = true;

        cbIfLoaded();
      });
    }
    else {
      backgroundImageLoaded = true;
    }

    if (serialized.overlayImage) {
      this.setOverlayImage(serialized.overlayImage, function() {

        _this.overlayImageLeft = serialized.overlayImageLeft || 0;
        _this.overlayImageTop = serialized.overlayImageTop || 0;

        _this.renderAll();
        overlayImageLoaded = true;

        cbIfLoaded();
      });
    }
    else {
      overlayImageLoaded = true;
    }

    if (serialized.background) {
      this.setBackgroundColor(serialized.background, function() {

        _this.renderAll();
        backgroundPatternLoaded = true;

        cbIfLoaded();
      });
    }
    else {
      backgroundPatternLoaded = true;
    }

    if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background) {
      callback && callback();
    }
  },

  /**
   * @private
   * @param {Array} objects
   * @param {Function} callback
   */
  _enlivenObjects: function (objects, callback) {
    var _this = this;

    if (objects.length === 0) {
      callback && callback();
    }

    var renderOnAddition = this.renderOnAddition;
    this.renderOnAddition = false;

    fabric.util.enlivenObjects(objects, function(enlivenedObjects) {
      enlivenedObjects.forEach(function(obj, index) {
        _this.insertAt(obj, index, true);
      });

      _this.renderOnAddition = renderOnAddition;
      callback && callback();
    });
  },

  /**
   * @private
   * @param {String} format
   * @param {Function} callback
   */
  _toDataURL: function (format, callback) {
    this.clone(function (clone) {
      callback(clone.toDataURL(format));
    });
  },

  /**
   * @private
   * @param {String} format
   * @param {Number} multiplier
   * @param {Function} callback
   */
  _toDataURLWithMultiplier: function (format, multiplier, callback) {
    this.clone(function (clone) {
      callback(clone.toDataURLWithMultiplier(format, multiplier));
    });
  },

  /**
   * Clones canvas instance
   * @param {Object} [callback] Receives cloned instance as a first argument
   */
  clone: function (callback) {
    var data = JSON.stringify(this);
    this.cloneWithoutData(function(clone) {
      clone.loadFromJSON(data, function() {
        callback && callback(clone);
      });
    });
  },

  /**
   * Clones canvas instance without cloning existing data.
   * This essentially copies canvas dimensions, clipping properties, etc.
   * but leaves data empty (so that you can populate it with your own)
   * @param {Object} [callback] Receives cloned instance as a first argument
   */
  cloneWithoutData: function(callback) {
    var el = fabric.document.createElement('canvas');

    el.width = this.getWidth();
    el.height = this.getHeight();

    var clone = new fabric.Canvas(el);
    clone.clipTo = this.clipTo;
    if (this.backgroundImage) {
      clone.setBackgroundImage(this.backgroundImage.src, function() {
        clone.renderAll();
        callback && callback(clone);
      });
      clone.backgroundImageOpacity = this.backgroundImageOpacity;
      clone.backgroundImageStretch = this.backgroundImageStretch;
    }
    else {
      callback && callback(clone);
    }
  }
});
<|endoftext|>


<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
 * @emails oncall+draft_js
 */

'use strict';

import type {DraftInlineStyle} from 'DraftInlineStyle';

const {Map, OrderedSet, Record} = require('immutable');

// Immutable.map is typed such that the value for every key in the map
// must be the same type
type CharacterMetadataConfigValueType = DraftInlineStyle | ?string;
type CharacterMetadataConfigRawValueType = Array<string> | ?string;

export type CharacterMetadataRawConfig = {
  style?: CharacterMetadataConfigRawValueType,
  entity?: CharacterMetadataConfigRawValueType,
  ...
};

type CharacterMetadataConfig = interface {
  style?: CharacterMetadataConfigValueType,
  entity?: CharacterMetadataConfigValueType,
};

const EMPTY_SET = OrderedSet();

const defaultRecord: CharacterMetadataConfig = {
  style: EMPTY_SET,
  entity: null,
};

const CharacterMetadataRecord = (Record(defaultRecord): any);

class CharacterMetadata extends CharacterMetadataRecord {
  getStyle(): DraftInlineStyle {
    return this.get('style');
  }

  getEntity(): ?string {
    return this.get('entity');
  }

  hasStyle(style: string): boolean {
    return this.getStyle().includes(style);
  }

  static applyStyle(
    record: CharacterMetadata,
    style: string,
  ): CharacterMetadata {
    const withStyle = record.set('style', record.getStyle().add(style));
    return CharacterMetadata.create(withStyle);
  }

  static removeStyle(
    record: CharacterMetadata,
    style: string,
  ): CharacterMetadata {
    const withoutStyle = record.set('style', record.getStyle().remove(style));
    return CharacterMetadata.create(withoutStyle);
  }

  static applyEntity(
    record: CharacterMetadata,
    entityKey: ?string,
  ): CharacterMetadata {
    const withEntity =
      record.getEntity() === entityKey
        ? record
        : record.set('entity', entityKey);
    return CharacterMetadata.create(withEntity);
  }

  /**
   * Use this function instead of the `CharacterMetadata` constructor.
   * Since most content generally uses only a very small number of
   * style/entity permutations, we can reuse these objects as often as
   * possible.
   */
  static create(config?: CharacterMetadataConfig): CharacterMetadata {
    if (!config) {
      return EMPTY;
    }

    const defaultConfig: CharacterMetadataConfig = {
      style: EMPTY_SET,
      entity: (null: ?string),
    };

    // Fill in unspecified properties, if necessary.
    // $FlowFixMe[incompatible-call]
    const configMap = Map(defaultConfig).merge(config);

    const existing: ?CharacterMetadata = pool.get(configMap);
    if (existing) {
      return existing;
    }

    const newCharacter = new CharacterMetadata(configMap);
    pool = pool.set(configMap, newCharacter);
    return newCharacter;
  }

  static fromJS({
    style,
    entity,
  }: CharacterMetadataRawConfig): CharacterMetadata {
    return new CharacterMetadata({
      style: Array.isArray(style) ? OrderedSet(style) : style,
      entity: Array.isArray(entity) ? OrderedSet(entity) : entity,
    });
  }
}

const EMPTY = new CharacterMetadata();
let pool: Map<Map<any, any>, CharacterMetadata> = Map([
  [Map(defaultRecord), EMPTY],
]);

CharacterMetadata.EMPTY = EMPTY;

module.exports = CharacterMetadata;
<commit_msg>Daily removal of unused Flow suppressions<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow
 * @emails oncall+draft_js
 */

'use strict';

import type {DraftInlineStyle} from 'DraftInlineStyle';

const {Map, OrderedSet, Record} = require('immutable');

// Immutable.map is typed such that the value for every key in the map
// must be the same type
type CharacterMetadataConfigValueType = DraftInlineStyle | ?string;
type CharacterMetadataConfigRawValueType = Array<string> | ?string;

export type CharacterMetadataRawConfig = {
  style?: CharacterMetadataConfigRawValueType,
  entity?: CharacterMetadataConfigRawValueType,
  ...
};

type CharacterMetadataConfig = interface {
  style?: CharacterMetadataConfigValueType,
  entity?: CharacterMetadataConfigValueType,
};

const EMPTY_SET = OrderedSet();

const defaultRecord: CharacterMetadataConfig = {
  style: EMPTY_SET,
  entity: null,
};

const CharacterMetadataRecord = (Record(defaultRecord): any);

class CharacterMetadata extends CharacterMetadataRecord {
  getStyle(): DraftInlineStyle {
    return this.get('style');
  }

  getEntity(): ?string {
    return this.get('entity');
  }

  hasStyle(style: string): boolean {
    return this.getStyle().includes(style);
  }

  static applyStyle(
    record: CharacterMetadata,
    style: string,
  ): CharacterMetadata {
    const withStyle = record.set('style', record.getStyle().add(style));
    return CharacterMetadata.create(withStyle);
  }

  static removeStyle(
    record: CharacterMetadata,
    style: string,
  ): CharacterMetadata {
    const withoutStyle = record.set('style', record.getStyle().remove(style));
    return CharacterMetadata.create(withoutStyle);
  }

  static applyEntity(
    record: CharacterMetadata,
    entityKey: ?string,
  ): CharacterMetadata {
    const withEntity =
      record.getEntity() === entityKey
        ? record
        : record.set('entity', entityKey);
    return CharacterMetadata.create(withEntity);
  }

  /**
   * Use this function instead of the `CharacterMetadata` constructor.
   * Since most content generally uses only a very small number of
   * style/entity permutations, we can reuse these objects as often as
   * possible.
   */
  static create(config?: CharacterMetadataConfig): CharacterMetadata {
    if (!config) {
      return EMPTY;
    }

    const defaultConfig: CharacterMetadataConfig = {
      style: EMPTY_SET,
      entity: (null: ?string),
    };

    // Fill in unspecified properties, if necessary.
    const configMap = Map(defaultConfig).merge(config);

    const existing: ?CharacterMetadata = pool.get(configMap);
    if (existing) {
      return existing;
    }

    const newCharacter = new CharacterMetadata(configMap);
    pool = pool.set(configMap, newCharacter);
    return newCharacter;
  }

  static fromJS({
    style,
    entity,
  }: CharacterMetadataRawConfig): CharacterMetadata {
    return new CharacterMetadata({
      style: Array.isArray(style) ? OrderedSet(style) : style,
      entity: Array.isArray(entity) ? OrderedSet(entity) : entity,
    });
  }
}

const EMPTY = new CharacterMetadata();
let pool: Map<Map<any, any>, CharacterMetadata> = Map([
  [Map(defaultRecord), EMPTY],
]);

CharacterMetadata.EMPTY = EMPTY;

module.exports = CharacterMetadata;
<|endoftext|>


<commit_before><commit_msg>Make RoomPublishSetting import-skinnable<commit_after><|endoftext|>


<commit_before>var fs = require('fs')
var MediaElementWrapper = require('../')
var path = require('path')
var stream = require('stream')
var test = require('tape')

var FILE = fs.readFileSync(path.join(__dirname, 'test.mp4'))
var CODEC_TYPE = 'video/mp4; codecs="avc1.42e01e"'

test('basic test', function (t) {
  t.plan(2)

  var elem = createElem('video')
  var readable = new stream.PassThrough()
  var wrapper = new MediaElementWrapper(elem)
  var writable = wrapper.createWriteStream(CODEC_TYPE)

  readable.on('error', function (err) { t.fail(err) })
  writable.on('error', function (err) { t.fail(err) })
  elem.addEventListener('error', function (err) { t.fail(err) })

  elem.addEventListener('playing', function () {
    t.pass('got the "playing" event')
  })

  elem.addEventListener('progress', onProgress)

  function onProgress () {
    t.pass('got a "progress" event')
    elem.removeEventListener('progress', onProgress)
  }

  readable.pipe(writable)
  readable.write(FILE)
})

// Don't fail when createWriteStream() is called twice before mediasource opens
// See: https://github.com/feross/mediasource/pull/5
test('call createWriteStream() twice immediately', function (t) {
  t.plan(3)

  var elem = createElem('video')
  var readable = new stream.PassThrough()
  var wrapper = new MediaElementWrapper(elem)

  var writable = wrapper.createWriteStream(CODEC_TYPE)

  t.doesNotThrow(function () {
    writable = wrapper.createWriteStream(writable)
  })

  readable.on('error', function (err) { t.fail(err) })
  writable.on('error', function (err) { t.fail(err) })
  elem.addEventListener('error', function (err) { t.fail(err) })

  elem.addEventListener('playing', function () {
    t.pass('got the "playing" event')
  })

  elem.addEventListener('progress', onProgress)

  function onProgress () {
    t.pass('got a "progress" event')
    elem.removeEventListener('progress', onProgress)
  }

  readable.pipe(writable)
  readable.write(FILE)
})

function createElem (tagName) {
  var elem = document.createElement(tagName)
  elem.controls = true
  elem.muted = true // make autoplay work
  elem.autoplay = true // for chrome
  document.body.insertBefore(elem, document.body.firstChild)
  return elem
}
<commit_msg>pass tests on browsers which lack mediasource support<commit_after>var fs = require('fs')
var MediaElementWrapper = require('../')
var path = require('path')
var stream = require('stream')
var test = require('tape')

var FILE = fs.readFileSync(path.join(__dirname, 'test.mp4'))
var CODEC_TYPE = 'video/mp4; codecs="avc1.42e01e"'

if (!window.MediaSource) {
  test.only('MediaSource support', (t) => {
    t.pass('browser lacks support')
    t.end()
  })
}

test('basic test', function (t) {
  t.plan(2)

  var elem = createElem('video')
  var readable = new stream.PassThrough()
  var wrapper = new MediaElementWrapper(elem)
  var writable = wrapper.createWriteStream(CODEC_TYPE)

  readable.on('error', function (err) { t.fail(err) })
  writable.on('error', function (err) { t.fail(err) })
  elem.addEventListener('error', function (err) { t.fail(err) })

  elem.addEventListener('playing', function () {
    t.pass('got the "playing" event')
  })

  elem.addEventListener('progress', onProgress)

  function onProgress () {
    t.pass('got a "progress" event')
    elem.removeEventListener('progress', onProgress)
  }

  readable.pipe(writable)
  readable.write(FILE)
})

// Don't fail when createWriteStream() is called twice before mediasource opens
// See: https://github.com/feross/mediasource/pull/5
test('call createWriteStream() twice immediately', function (t) {
  t.plan(3)

  var elem = createElem('video')
  var readable = new stream.PassThrough()
  var wrapper = new MediaElementWrapper(elem)

  var writable = wrapper.createWriteStream(CODEC_TYPE)

  t.doesNotThrow(function () {
    writable = wrapper.createWriteStream(writable)
  })

  readable.on('error', function (err) { t.fail(err) })
  writable.on('error', function (err) { t.fail(err) })
  elem.addEventListener('error', function (err) { t.fail(err) })

  elem.addEventListener('playing', function () {
    t.pass('got the "playing" event')
  })

  elem.addEventListener('progress', onProgress)

  function onProgress () {
    t.pass('got a "progress" event')
    elem.removeEventListener('progress', onProgress)
  }

  readable.pipe(writable)
  readable.write(FILE)
})

function createElem (tagName) {
  var elem = document.createElement(tagName)
  elem.controls = true
  elem.muted = true // make autoplay work
  elem.autoplay = true // for chrome
  document.body.insertBefore(elem, document.body.firstChild)
  return elem
}
<|endoftext|>


<commit_before>
var test = require('tape')

test('ipSet.contains respects ipSet.add', function (t) {
  var ipSet = require('../')()
  var localhost = '127.0.0.1'

  t.notOk(ipSet.contains(localhost))
  ipSet.add(localhost)
  t.ok(ipSet.contains(localhost))
  t.end()
})

// TODO: more thorough unit tests

<commit_msg>Expand test coverage<commit_after>
const test = require('tape')
const ipSet = require('../');

test('ipSet.contains respects ipSet.add with only a start', function(t) {
  const set = ipSet();
  const ip = '127.0.0.1';

  t.notOk(set.contains(ip))
  set.add(ip)
  t.ok(set.contains(ip))
  t.end()
});

test('ipSet.contains respects ipSet.add with a start and an end', function(t) {
  const set = ipSet();
  const ips = ['192.168.1.0', '192.168.1.255'];

  set.add(ips[0], ips[1])
  t.ok(set.contains(ips[0]))
  t.ok(set.contains(ips[1]))
  t.ok(set.contains('192.168.1.123'))
  t.notOk(set.contains('192.168.2.0'))

  t.end()
});

test('IPv6', function(t) {
  const set = ipSet();
  const ip = '0:0:0:0:0:ffff:7f00:1' // 127.0.0.1
  const publicIP = '2607:f8b0:4004:811::200e'; // google
  const ipv4 = '127.0.0.1';

  t.notOk(set.contains(ip))
  set.add(ip)
  t.ok(set.contains(ip))

  t.notOk(set.contains(publicIP))
  set.add(publicIP)
  t.ok(set.contains(publicIP))

  t.notOk(set.contains('127.0.0.1'))
  set.add(ipv4)
  t.ok(set.contains(ipv4))

  t.end()
});

// Fails on checking it doesn't contain a value outside the range.
test.skip('IPv6 range', function(t) {
  const set = ipSet();
  const start = '0:0:0:0:0:0:0:1'
  const mid1 = '0:0:0:0:0:0:0:9'
  const mid2 = '0:0:0:0:0:0:0:a'
  const end = '0:0:0:0:0:0:0:f'
  const outside = '0:0:0:0:0:0:1:0'

  set.add(start, end)
  t.ok(set.contains(start))
  t.ok(set.contains(end))
  t.ok(set.contains(mid1))
  t.ok(set.contains(mid2))
  t.ok(set.contains(mid2))
  t.notOk(set.contains(outside))

  t.end()
})

<|endoftext|>


<commit_before>var common = require('./common')
var Peer = require('../')
var test = require('tape')

var config
test('get config', function (t) {
  common.getConfig(function (err, _config) {
    if (err) return t.fail(err)
    config = _config
    t.end()
  })
})

test('detect WebRTC support', function (t) {
  t.equal(Peer.WEBRTC_SUPPORT, typeof window !== 'undefined', 'builtin webrtc support')
  t.end()
})

test('create peer without options', function (t) {
  t.plan(1)

  if (process.browser) {
    var peer
    t.doesNotThrow(function () {
      peer = new Peer()
    })
    peer.destroy()
  } else {
    t.pass('Skip no-option test in Node.js, since the wrtc option is required')
  }
})

test('signal event gets emitted', function (t) {
  t.plan(2)

  var peer = new Peer({ config: config, initiator: true, wrtc: common.wrtc })
  peer.once('signal', function () {
    t.pass('got signal event')
    peer.on('close', function () { t.pass('peer destroyed') })
    peer.destroy()
  })
})

test('signal event does not get emitted by non-initiator', function (t) {
  var peer = new Peer({ config: config, initiator: false, wrtc: common.wrtc })
  peer.once('signal', function () {
    t.fail('got signal event')
    peer.on('close', function () { t.pass('peer destroyed') })
    peer.destroy()
  })

  setTimeout(() => {
    t.pass('did not get signal after 1000ms')
    t.end()
  }, 1000)
})

test('signal event does not get emitted by non-initiator with stream', function (t) {
  var peer = new Peer({
    config: config,
    stream: common.getMediaStream(),
    initiator: false,
    wrtc: common.wrtc
  })
  peer.once('signal', function () {
    t.fail('got signal event')
    peer.on('close', function () { t.pass('peer destroyed') })
    peer.destroy()
  })

  setTimeout(() => {
    t.pass('did not get signal after 1000ms')
    t.end()
  }, 1000)
})

test('data send/receive text', function (t) {
  t.plan(10)

  var peer1 = new Peer({ config: config, initiator: true, wrtc: common.wrtc })
  var peer2 = new Peer({ config: config, wrtc: common.wrtc })

  var numSignal1 = 0
  peer1.on('signal', function (data) {
    numSignal1 += 1
    peer2.signal(data)
  })

  var numSignal2 = 0
  peer2.on('signal', function (data) {
    numSignal2 += 1
    peer1.signal(data)
  })

  peer1.on('connect', tryTest)
  peer2.on('connect', tryTest)

  function tryTest () {
    if (!peer1.connected || !peer2.connected) return

    t.ok(numSignal1 >= 1)
    t.ok(numSignal2 >= 1)
    t.equal(peer1.initiator, true, 'peer1 is initiator')
    t.equal(peer2.initiator, false, 'peer2 is not initiator')

    peer1.send('sup peer2')
    peer2.on('data', function (data) {
      t.ok(Buffer.isBuffer(data), 'data is Buffer')
      t.equal(data.toString(), 'sup peer2', 'got correct message')

      peer2.send('sup peer1')
      peer1.on('data', function (data) {
        t.ok(Buffer.isBuffer(data), 'data is Buffer')
        t.equal(data.toString(), 'sup peer1', 'got correct message')

        peer1.on('close', function () { t.pass('peer1 destroyed') })
        peer1.destroy()
        peer2.on('close', function () { t.pass('peer2 destroyed') })
        peer2.destroy()
      })
    })
  }
})

test('sdpTransform function is called', function (t) {
  t.plan(3)

  var peer1 = new Peer({ config: config, initiator: true, wrtc: common.wrtc })
  var peer2 = new Peer({ config: config, sdpTransform: sdpTransform, wrtc: common.wrtc })

  function sdpTransform (sdp) {
    t.equal(typeof sdp, 'string', 'got a string as SDP')
    setTimeout(function () {
      peer1.on('close', function () { t.pass('peer1 destroyed') })
      peer1.destroy()
      peer2.on('close', function () { t.pass('peer2 destroyed') })
      peer2.destroy()
    }, 0)
    return sdp
  }

  peer1.on('signal', function (data) {
    peer2.signal(data)
  })

  peer2.on('signal', function (data) {
    peer1.signal(data)
  })
})

test('old constraint formats are used', function (t) {
  t.plan(3)

  var constraints = {
    mandatory: {
      OfferToReceiveAudio: true,
      OfferToReceiveVideo: true
    }
  }

  var peer1 = new Peer({ config: config, initiator: true, wrtc: common.wrtc, constraints: constraints })
  var peer2 = new Peer({ config: config, wrtc: common.wrtc, constraints: constraints })

  peer1.on('signal', function (data) {
    peer2.signal(data)
  })

  peer2.on('signal', function (data) {
    peer1.signal(data)
  })

  peer1.on('connect', function () {
    t.pass('peers connected')
    peer1.on('close', function () { t.pass('peer1 destroyed') })
    peer1.destroy()
    peer2.on('close', function () { t.pass('peer2 destroyed') })
    peer2.destroy()
  })
})

test('new constraint formats are used', function (t) {
  t.plan(3)

  var constraints = {
    offerToReceiveAudio: true,
    offerToReceiveVideo: true
  }

  var peer1 = new Peer({ config: config, initiator: true, wrtc: common.wrtc, constraints: constraints })
  var peer2 = new Peer({ config: config, wrtc: common.wrtc, constraints: constraints })

  peer1.on('signal', function (data) {
    peer2.signal(data)
  })

  peer2.on('signal', function (data) {
    peer1.signal(data)
  })

  peer1.on('connect', function () {
    t.pass('peers connected')
    peer1.on('close', function () { t.pass('peer1 destroyed') })
    peer1.destroy()
    peer2.on('close', function () { t.pass('peer2 destroyed') })
    peer2.destroy()
  })
})

test('ensure remote address and port are available right after connection', function (t) {
  if (common.isBrowser('safari') || common.isBrowser('ios')) {
    t.pass('Skip on Safari and iOS which do not support modern getStats() calls')
    t.end()
    return
  }

  t.plan(7)

  var peer1 = new Peer({ config: config, initiator: true, wrtc: common.wrtc })
  var peer2 = new Peer({ config: config, wrtc: common.wrtc })

  peer1.on('signal', function (data) {
    peer2.signal(data)
  })

  peer2.on('signal', function (data) {
    peer1.signal(data)
  })

  peer1.on('connect', function () {
    t.pass('peers connected')

    t.ok(peer1.remoteAddress, 'peer1 remote address is present')
    t.ok(peer1.remotePort, 'peer1 remote port is present')

    peer2.on('connect', function () {
      t.ok(peer2.remoteAddress, 'peer2 remote address is present')
      t.ok(peer2.remotePort, 'peer2 remote port is present')

      peer1.on('close', function () { t.pass('peer1 destroyed') })
      peer1.destroy()
      peer2.on('close', function () { t.pass('peer2 destroyed') })
      peer2.destroy()
    })
  })
})
<commit_msg>test: can detect error when RTCPeerConstructor throws<commit_after>var common = require('./common')
var Peer = require('../')
var test = require('tape')

var config
test('get config', function (t) {
  common.getConfig(function (err, _config) {
    if (err) return t.fail(err)
    config = _config
    t.end()
  })
})

test('detect WebRTC support', function (t) {
  t.equal(Peer.WEBRTC_SUPPORT, typeof window !== 'undefined', 'builtin webrtc support')
  t.end()
})

test('create peer without options', function (t) {
  t.plan(1)

  if (process.browser) {
    var peer
    t.doesNotThrow(function () {
      peer = new Peer()
    })
    peer.destroy()
  } else {
    t.pass('Skip no-option test in Node.js, since the wrtc option is required')
  }
})

test('can detect error when RTCPeerConstructor throws', function (t) {
  t.plan(1)

  var peer = new Peer({ wrtc: { RTCPeerConnection: null } })
  peer.once('error', function () {
    t.pass('got error event')
    peer.destroy()
  })
})

test('signal event gets emitted', function (t) {
  t.plan(2)

  var peer = new Peer({ config: config, initiator: true, wrtc: common.wrtc })
  peer.once('signal', function () {
    t.pass('got signal event')
    peer.on('close', function () { t.pass('peer destroyed') })
    peer.destroy()
  })
})

test('signal event does not get emitted by non-initiator', function (t) {
  var peer = new Peer({ config: config, initiator: false, wrtc: common.wrtc })
  peer.once('signal', function () {
    t.fail('got signal event')
    peer.on('close', function () { t.pass('peer destroyed') })
    peer.destroy()
  })

  setTimeout(() => {
    t.pass('did not get signal after 1000ms')
    t.end()
  }, 1000)
})

test('signal event does not get emitted by non-initiator with stream', function (t) {
  var peer = new Peer({
    config: config,
    stream: common.getMediaStream(),
    initiator: false,
    wrtc: common.wrtc
  })
  peer.once('signal', function () {
    t.fail('got signal event')
    peer.on('close', function () { t.pass('peer destroyed') })
    peer.destroy()
  })

  setTimeout(() => {
    t.pass('did not get signal after 1000ms')
    t.end()
  }, 1000)
})

test('data send/receive text', function (t) {
  t.plan(10)

  var peer1 = new Peer({ config: config, initiator: true, wrtc: common.wrtc })
  var peer2 = new Peer({ config: config, wrtc: common.wrtc })

  var numSignal1 = 0
  peer1.on('signal', function (data) {
    numSignal1 += 1
    peer2.signal(data)
  })

  var numSignal2 = 0
  peer2.on('signal', function (data) {
    numSignal2 += 1
    peer1.signal(data)
  })

  peer1.on('connect', tryTest)
  peer2.on('connect', tryTest)

  function tryTest () {
    if (!peer1.connected || !peer2.connected) return

    t.ok(numSignal1 >= 1)
    t.ok(numSignal2 >= 1)
    t.equal(peer1.initiator, true, 'peer1 is initiator')
    t.equal(peer2.initiator, false, 'peer2 is not initiator')

    peer1.send('sup peer2')
    peer2.on('data', function (data) {
      t.ok(Buffer.isBuffer(data), 'data is Buffer')
      t.equal(data.toString(), 'sup peer2', 'got correct message')

      peer2.send('sup peer1')
      peer1.on('data', function (data) {
        t.ok(Buffer.isBuffer(data), 'data is Buffer')
        t.equal(data.toString(), 'sup peer1', 'got correct message')

        peer1.on('close', function () { t.pass('peer1 destroyed') })
        peer1.destroy()
        peer2.on('close', function () { t.pass('peer2 destroyed') })
        peer2.destroy()
      })
    })
  }
})

test('sdpTransform function is called', function (t) {
  t.plan(3)

  var peer1 = new Peer({ config: config, initiator: true, wrtc: common.wrtc })
  var peer2 = new Peer({ config: config, sdpTransform: sdpTransform, wrtc: common.wrtc })

  function sdpTransform (sdp) {
    t.equal(typeof sdp, 'string', 'got a string as SDP')
    setTimeout(function () {
      peer1.on('close', function () { t.pass('peer1 destroyed') })
      peer1.destroy()
      peer2.on('close', function () { t.pass('peer2 destroyed') })
      peer2.destroy()
    }, 0)
    return sdp
  }

  peer1.on('signal', function (data) {
    peer2.signal(data)
  })

  peer2.on('signal', function (data) {
    peer1.signal(data)
  })
})

test('old constraint formats are used', function (t) {
  t.plan(3)

  var constraints = {
    mandatory: {
      OfferToReceiveAudio: true,
      OfferToReceiveVideo: true
    }
  }

  var peer1 = new Peer({ config: config, initiator: true, wrtc: common.wrtc, constraints: constraints })
  var peer2 = new Peer({ config: config, wrtc: common.wrtc, constraints: constraints })

  peer1.on('signal', function (data) {
    peer2.signal(data)
  })

  peer2.on('signal', function (data) {
    peer1.signal(data)
  })

  peer1.on('connect', function () {
    t.pass('peers connected')
    peer1.on('close', function () { t.pass('peer1 destroyed') })
    peer1.destroy()
    peer2.on('close', function () { t.pass('peer2 destroyed') })
    peer2.destroy()
  })
})

test('new constraint formats are used', function (t) {
  t.plan(3)

  var constraints = {
    offerToReceiveAudio: true,
    offerToReceiveVideo: true
  }

  var peer1 = new Peer({ config: config, initiator: true, wrtc: common.wrtc, constraints: constraints })
  var peer2 = new Peer({ config: config, wrtc: common.wrtc, constraints: constraints })

  peer1.on('signal', function (data) {
    peer2.signal(data)
  })

  peer2.on('signal', function (data) {
    peer1.signal(data)
  })

  peer1.on('connect', function () {
    t.pass('peers connected')
    peer1.on('close', function () { t.pass('peer1 destroyed') })
    peer1.destroy()
    peer2.on('close', function () { t.pass('peer2 destroyed') })
    peer2.destroy()
  })
})

test('ensure remote address and port are available right after connection', function (t) {
  if (common.isBrowser('safari') || common.isBrowser('ios')) {
    t.pass('Skip on Safari and iOS which do not support modern getStats() calls')
    t.end()
    return
  }

  t.plan(7)

  var peer1 = new Peer({ config: config, initiator: true, wrtc: common.wrtc })
  var peer2 = new Peer({ config: config, wrtc: common.wrtc })

  peer1.on('signal', function (data) {
    peer2.signal(data)
  })

  peer2.on('signal', function (data) {
    peer1.signal(data)
  })

  peer1.on('connect', function () {
    t.pass('peers connected')

    t.ok(peer1.remoteAddress, 'peer1 remote address is present')
    t.ok(peer1.remotePort, 'peer1 remote port is present')

    peer2.on('connect', function () {
      t.ok(peer2.remoteAddress, 'peer2 remote address is present')
      t.ok(peer2.remotePort, 'peer2 remote port is present')

      peer1.on('close', function () { t.pass('peer1 destroyed') })
      peer1.destroy()
      peer2.on('close', function () { t.pass('peer2 destroyed') })
      peer2.destroy()
    })
  })
})
<|endoftext|>


<commit_before>import fs from 'fs'
import bulbo from '../src/bulbo'

import {expect} from 'chai'
import rimraf from 'rimraf'
import request from 'superagent'
import vinylServe from 'vinyl-serve'
import through from 'through'
import browserify from 'browserify'

const SERVER_LAUNCH_WAIT = 800
const BUILD_WAIT = 400

describe('bulbo', () => {
  beforeEach(() => {
    bulbo.clear()
  })

  describe('asset', () => {
    it('registers the asset', () => {
      bulbo.asset('test/fixture/**/*.js')
      expect(bulbo.isEmpty()).to.be.false
    })

    it('returns the asset\'s modifier', () => {
      expect(bulbo.asset('test/fixture/**/*.js')).to.be.an('object')
      expect(bulbo.asset('test/fixture/**/*.js').watch).to.be.a('function')
      expect(bulbo.asset('test/fixture/**/*.js').watchOptions).to.be.a('function')
      expect(bulbo.asset('test/fixture/**/*.js').base).to.be.a('function')
    })

    describe('.pipe', () => {
      it('sets the transform to the asset', done => {
        bulbo
        .asset('test/fixture/js/{foo,bar}.js')
        .base('test/fixture')
        .pipe(through(function (file) {
          file.contents = browserify(file.path).bundle()

          this.queue(file)
        }))

        bulbo.build().then(() => {
          const contents = fs.readFileSync('build/js/foo.js').toString()

          expect(contents).to.contain('This is foo.js')
          expect(contents).to.contain('This is bar.js')

          rimraf('build', done)
        }).catch(done)
      })
    })
  })

  describe('build', () => {
    it('builds the assets and put them in build/ dir', done => {
      bulbo.asset('test/fixture/**/*.js')

      bulbo.build().then(() => {
        expect(fs.readFileSync('build/js/foo.js').toString()).to.have.length.above(1)

        rimraf('build', done)
      })
    })

    it('does not stop at highWaterMark(=16) files', done => {
      bulbo.asset('test/fixture/**/*.js')

      bulbo.build().then(() => {
        expect(fs.readFileSync('build/js/0.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/1.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/2.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/3.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/4.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/5.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/6.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/7.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/8.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/9.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/10.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/11.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/12.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/13.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/14.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/15.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/16.js').toString()).to.have.length.above(1)

        rimraf('build', done)
      })
    })

    it('does not throw when assets are empty', done => {
      bulbo.build()

      setTimeout(done, BUILD_WAIT)
    })
  })

  describe('serve', () => {
    it('serves the assets at port 7100', done => {
      bulbo.asset('test/fixture/**/*.js')

      bulbo.serve().then(() => {
        setTimeout(() => {
          request.get('0.0.0.0:7100/js/foo.js').buffer().end((err, res) => {
            if (err) { done(err) }

            expect(res.text).to.contain('This is foo.js')

            vinylServe.stop(7100)

            done()
          })
        }, SERVER_LAUNCH_WAIT)
      })
    })

    it('does not throw when the assets are empty', done => {
      bulbo.serve()

      setTimeout(() => {
        vinylServe.stop(7100)

        done()
      }, SERVER_LAUNCH_WAIT)
    })
  })

  describe('port', () => {
    it('sets the port number', done => {
      bulbo.port(8500)

      bulbo.serve().then(() => {
        request.get('0.0.0.0:8500/__bulbo__').end((err, res) => {
          vinylServe.stop(8500)

          done(err)
        })
      })
    })
  })

  describe('dest', () => {
    it('sets the build destination', done => {
      bulbo.dest('build/dist')

      bulbo.asset('test/fixture/**/*.js')

      bulbo.build().then(() => {
        expect(fs.readFileSync('build/dist/js/foo.js').toString()).to.have.length.above(1)

        rimraf('build', done)
      })
    })
  })
})
<commit_msg>fix(test): fix test settings<commit_after>const fs = require('fs')
const bulbo = require('../src/bulbo')

const {expect} = require('chai')
import rimraf from 'rimraf'
import request from 'superagent'
import vinylServe from 'vinyl-serve'
import through from 'through'
import browserify from 'browserify'

const SERVER_LAUNCH_WAIT = 800
const BUILD_WAIT = 400

describe('bulbo', () => {
  beforeEach(() => {
    bulbo.clear()
    bulbo.setLogger(require('../src/util/logger')('bulbo'))
  })

  describe('asset', () => {
    it('registers the asset', () => {
      bulbo.asset('test/fixture/**/*.js')
      expect(bulbo.isEmpty()).to.be.false
    })

    it('returns the asset\'s modifier', () => {
      expect(bulbo.asset('test/fixture/**/*.js')).to.be.an('object')
      expect(bulbo.asset('test/fixture/**/*.js').watch).to.be.a('function')
      expect(bulbo.asset('test/fixture/**/*.js').watchOptions).to.be.a('function')
      expect(bulbo.asset('test/fixture/**/*.js').base).to.be.a('function')
    })

    describe('.pipe', () => {
      it('sets the transform to the asset', done => {
        bulbo
        .asset('test/fixture/js/{foo,bar}.js')
        .base('test/fixture')
        .pipe(through(function (file) {
          file.contents = browserify(file.path).bundle()

          this.queue(file)
        }))

        bulbo.build().then(() => {
          const contents = fs.readFileSync('build/js/foo.js').toString()

          expect(contents).to.contain('This is foo.js')
          expect(contents).to.contain('This is bar.js')

          rimraf('build', done)
        }).catch(done)
      })
    })
  })

  describe('build', () => {
    it('builds the assets and put them in build/ dir', done => {
      bulbo.asset('test/fixture/**/*.js')

      bulbo.build().then(() => {
        expect(fs.readFileSync('build/js/foo.js').toString()).to.have.length.above(1)

        rimraf('build', done)
      })
    })

    it('does not stop at highWaterMark(=16) files', done => {
      bulbo.asset('test/fixture/**/*.js')

      bulbo.build().then(() => {
        expect(fs.readFileSync('build/js/0.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/1.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/2.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/3.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/4.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/5.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/6.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/7.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/8.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/9.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/10.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/11.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/12.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/13.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/14.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/15.js').toString()).to.have.length.above(1)
        expect(fs.readFileSync('build/js/16.js').toString()).to.have.length.above(1)

        rimraf('build', done)
      })
    })

    it('does not throw when assets are empty', done => {
      bulbo.build()

      setTimeout(done, BUILD_WAIT)
    })
  })

  describe('serve', () => {
    it('serves the assets at port 7100', done => {
      bulbo.asset('test/fixture/**/*.js')

      bulbo.serve().then(() => {
        setTimeout(() => {
          request.get('0.0.0.0:7100/js/foo.js').buffer().end((err, res) => {
            if (err) { done(err) }

            expect(res.text).to.contain('This is foo.js')

            vinylServe.stop(7100)

            done()
          })
        }, SERVER_LAUNCH_WAIT)
      })
    })

    it('does not throw when the assets are empty', done => {
      bulbo.serve()

      setTimeout(() => {
        vinylServe.stop(7100)

        done()
      }, SERVER_LAUNCH_WAIT)
    })
  })

  describe('port', () => {
    it('sets the port number', done => {
      bulbo.port(8500)

      bulbo.serve().then(() => {
        request.get('0.0.0.0:8500/__bulbo__').end((err, res) => {
          vinylServe.stop(8500)

          done(err)
        })
      })
    })
  })

  describe('dest', () => {
    it('sets the build destination', done => {
      bulbo.dest('build/dist')

      bulbo.asset('test/fixture/**/*.js')

      bulbo.build().then(() => {
        expect(fs.readFileSync('build/dist/js/foo.js').toString()).to.have.length.above(1)

        rimraf('build', done)
      })
    })
  })
})
<|endoftext|>


<commit_before>var assert = require('assert');
var expect = require('chai').expect;

var crypto = require('crypto');

var Block = require('../lib/block');
var Chain = require('../lib/chain');
var Ledger = require('../lib/ledger');

var block = new Block(); // linked list
//var chain = new Chain(); // secured tree
var ledger = new Ledger(); // simple list

//var Machine = require('../lib/machine');

var genesis = {
  name: 'genesis',
  entropy: '00000000'
};

var zero = 'd9a3ed614805ffbc3c6e62cceae3339046f6bb7135b7d00fe9956bee65871f00';
var state = '44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a';

// test our own expectations.  best of luck.
// @consensus:
// @quest:
// > *Warning:* ahead lies death. # must be attributed to "Game Master"
//
describe('Chain', function () {
  it('should expose a constructor', function () {
    assert.equal(typeof Chain, 'function');
  });

  it('can generate a chain of 0 length', async function () {
    var chain = new Chain();
    var output = chain.compute();

    await chain._flush();
    await chain.storage.close();

    assert.equal(output.blocks.length, 0);
    assert.equal(output['@id'], state);
  });

  it('can generate a chain with a genesis block', async function () {
    var chain = new Chain();
    var block = new Block(genesis);

    block._sign();

    assert.equal(block['@id'], zero);

    await chain.append(block);

    var output = chain.compute();

    assert.equal(1, chain.blocks.length);
    assert.equal(JSON.stringify(chain['@data']), JSON.stringify([block['@id']]));
    assert.equal(chain.genesis, zero);

    await chain._flush();
    await chain.storage.close();
  });

  it('can generate a chain of non-zero length', async function () {
    var chain = new Chain();
    var genesis = new Block(genesis);

    genesis.compute();
    await chain.append(genesis);

    var num = 3;
    var last = genesis['@id'];
    for (var i = 0; i < num; i++) {
      var block = new Block({
        parent: last,
        entropy: crypto.randomBytes(8).toString('hex')
      });
      block.compute();
      last = block['@id'];
      await chain.append(block);
    }

    var output = chain.compute();

    await chain._flush();
    await chain.storage.close();

    assert.equal(output.blocks.length, 4);
  });

  it('can replay after shutting down', async function () {
    var chain = new Chain();
    var block = new Block(genesis);

    block.compute();

    await chain.append(block);

    var output = chain.compute();

    await chain.storage.close();

    var replay = new Chain();

    await replay._load();

    var original = replay.compute();

    await replay.store.close();

    assert.equal(original['@data'][0], zero);

  });
});
<commit_msg>Add missing migration for Chain test<commit_after>var assert = require('assert');
var expect = require('chai').expect;

var crypto = require('crypto');

var Block = require('../lib/block');
var Chain = require('../lib/chain');
var Ledger = require('../lib/ledger');

var block = new Block(); // linked list
//var chain = new Chain(); // secured tree
var ledger = new Ledger(); // simple list

//var Machine = require('../lib/machine');

var genesis = {
  name: 'genesis',
  entropy: '00000000'
};

var zero = 'd9a3ed614805ffbc3c6e62cceae3339046f6bb7135b7d00fe9956bee65871f00';
var state = '44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a';

// test our own expectations.  best of luck.
// @consensus:
// @quest:
// > *Warning:* ahead lies death. # must be attributed to "Game Master"
//
describe('Chain', function () {
  it('should expose a constructor', function () {
    assert.equal(typeof Chain, 'function');
  });

  it('can generate a chain of 0 length', async function () {
    var chain = new Chain();
    var output = chain.compute();

    await chain._flush();
    await chain.storage.close();

    assert.equal(output.blocks.length, 0);
    assert.equal(output['@id'], state);
  });

  it('can generate a chain with a genesis block', async function () {
    var chain = new Chain();
    var block = new Block(genesis);

    block._sign();

    assert.equal(block['@id'], zero);

    await chain.append(block);

    var output = chain.compute();

    assert.equal(1, chain.blocks.length);
    assert.equal(JSON.stringify(chain['@data']), JSON.stringify([block['@id']]));
    assert.equal(chain.genesis, zero);

    await chain._flush();
    await chain.storage.close();
  });

  it('can generate a chain of non-zero length', async function () {
    var chain = new Chain();
    var genesis = new Block(genesis);

    genesis.compute();
    await chain.append(genesis);

    var num = 3;
    var last = genesis['@id'];
    for (var i = 0; i < num; i++) {
      var block = new Block({
        parent: last,
        entropy: crypto.randomBytes(8).toString('hex')
      });
      block.compute();
      last = block['@id'];
      await chain.append(block);
    }

    var output = chain.compute();

    await chain._flush();
    await chain.storage.close();

    assert.equal(output.blocks.length, 4);
  });

  it('can replay after shutting down', async function () {
    var chain = new Chain();
    var block = new Block(genesis);

    block.compute();

    await chain.append(block);

    var output = chain.compute();

    await chain.storage.close();

    var replay = new Chain();

    await replay._load();

    var original = replay.compute();

    await replay.storage.close();

    assert.equal(original['@data'][0], zero);

  });
});
<|endoftext|>


<commit_before>var fs = require('fs'),
    sys = require('sys');
file = 'server.js';
fs.watchFile(file, function(curr, prev) {
    sys.puts("File was modified.");
});

console.log('serving file %s', file)<commit_msg>Remove test/edit whitespace<commit_after><|endoftext|>


<commit_before>'use strict'
var path = require('path')
var test = require('tap').test
var rimraf = require('rimraf')
var writeStream = require('../index.js')

var target = path.resolve(__dirname, 'test-chown')

test('chown works', function (t) {
  t.plan(1)
  var stream = writeStream(target, {chown: {uid: process.getuid(), gid: process.getgid()}})
  var hadError = false
  stream.on('error', function (er) {
    hadError = true
    console.error('#', er)
  })
  stream.on('close', function () {
    t.is(hadError, false, 'no errors before close')
  })
  stream.end()
})

test('chown fails', function (t) {
  t.plan(1)
  if (process.getuid() === 0) {
    t.pass("# SKIP - Can't test chown failures as root")
    return
  }
  var stream = writeStream(target, {chown: {uid: 0, gid: 0}})
  stream.on('error', function (er) {
    t.ok(er, 'got chown error before close')
  })
  stream.end()
})

test('cleanup', function (t) {
  rimraf.sync(target)
  t.end()
})
<commit_msg>test: Remove chown failure case<commit_after>'use strict'
var path = require('path')
var test = require('tap').test
var rimraf = require('rimraf')
var writeStream = require('../index.js')

var target = path.resolve(__dirname, 'test-chown')

test('chown works', function (t) {
  t.plan(1)
  var stream = writeStream(target, {chown: {uid: process.getuid(), gid: process.getgid()}})
  var hadError = false
  stream.on('error', function (er) {
    hadError = true
    console.error('#', er)
  })
  stream.on('close', function () {
    t.is(hadError, false, 'no errors before close')
  })
  stream.end()
})

test('cleanup', function (t) {
  rimraf.sync(target)
  t.end()
})
<|endoftext|>