<commit_before>import {
  TicketsCogs,
  PassphraseModalButton,
  ImportScriptIconButton,
  KeyBlueButton,
  InvisibleConfirmModalButton
} from "buttons";
import { AccountsSelect, NumTicketsInput } from "inputs";
import { FormattedMessage as T } from "react-intl";
import {
  TransitionMotionWrapper,
  ShowWarning,
  ExternalLink,
  Balance,
  Tooltip
} from "shared";

import "style/StakePool.less";

const purchaseLabel = () => (
  <T id="purchas.legacypurchaseTickets.purchaseBtn" m="Purchase" />
);

const PurchaseTicketsForm = ({
  isShowingAdvanced,
  getQuickBarComponent,
  getAdvancedComponent,
  getIsValid,
  handleOnKeyDown,
  numTicketsToBuy,
  onIncrementNumTickets,
  onDecrementNumTickets,
  onChangeNumTickets,
  onChangeAccount,
  onPurchaseTickets,
  onRevokeTickets,
  onToggleShowAdvanced,
  account,
  ticketPrice,
  willEnter,
  willLeave,
  toggleShowVsp,
  dismissBackupRedeemScript,
  onDismissBackupRedeemScript,
  isWatchingOnly,
  notMixedAccounts,
  getRunningIndicator
}) => (
  <>

          <T id="purchaseTickets.accountFrom.legacy" m="From" />:

        <AccountsSelect
          className="stakepool-purchase-ticket-input-select"
          filterAccounts={notMixedAccounts}
          {...{ account, onChange: onChangeAccount }}
        />

          <T id="purchaseTickets.ticketAmount.legacy" m="Amount" />:

        <NumTicketsInput
          required
          invalid={!getIsValid()}
          invalidMessage={
            <T
              id="purchaseTickets.errors.insufficientBalance.legacy"
              m="Not enough funds"
            />
          }
          numTickets={numTicketsToBuy}
          incrementNumTickets={onIncrementNumTickets}
          decrementNumTickets={onDecrementNumTickets}
          onChangeNumTickets={onChangeNumTickets}
          onKeyDown={handleOnKeyDown}
          showErrors={true}></NumTicketsInput>
        {getIsValid() && (

            <T
              id="purchaseTickets.validMsg.legacy"
              m="Total: {amount} Remaining: {remaining}"
              values={{
                amount: <Balance flat amount={numTicketsToBuy * ticketPrice} />,
                remaining: (
                  <Balance
                    flat
                    amount={account.spendable - numTicketsToBuy * ticketPrice}
                  />
                )
              }}
            />

        )}

        <TicketsCogs
          opened={!isShowingAdvanced}
          onClick={onToggleShowAdvanced}
        />
        <ImportScriptIconButton />

      <TransitionMotionWrapper
        {...{
          styles: !isShowingAdvanced
            ? getQuickBarComponent
            : getAdvancedComponent,
          willEnter: !isShowingAdvanced
            ? () => willEnter(270)
            : () => willEnter(80),
          willLeave
        }}
      />

    {!dismissBackupRedeemScript && (

        <ShowWarning
          warn={
            <T
              id="purchase.ticket.backup.redeem.warn"
              m="You must backup your redeem script. More information about it can be found at {link}"
              values={{
                link: (
                  <ExternalLink
                    href={
                      "https://docs.decred.org/wallets/decrediton/using-decrediton/#backup-redeem-script"
                    }>
                    <T id="purchase.ticket.decred.docs" m="Decred docs" />
                  </ExternalLink>
                )
              }}
            />
          }
        />

          <InvisibleConfirmModalButton
            modalTitle={<T id="purchase.ticket.modal.title" m="Dismiss" />}
            modalContent={
              <T
                id="purchase.ticket.modal.desc"
                m="Are you sure you want to dismiss this message? Make sure your redeem scripts are backed up."
              />
            }
            buttonLabel={
              <T id="purchase.ticket.dismiss.warn" m="Dismiss Message" />
            }
            onSubmit={() => onDismissBackupRedeemScript()}
            className="stakepool-content-send"
          />
          <KeyBlueButton
            className="vsp-warning-backup-redeem-button"
            onClick={() => toggleShowVsp(true)}>
            <T id="purchase.ticket.warn.button" m="Backup Redeem Scripts" />
          </KeyBlueButton>

    )}

      <PassphraseModalButton
        modalTitle={
          <T
            id="tickets.revokeConfirmations.legacy"
            m="Revoke Tickets Confirmation"
          />
        }
        className="stakepool-content-revoke-button"
        onSubmit={onRevokeTickets}
        buttonLabel={<T id="purchaseTickets.revokeBtn.legacy" m="Revoke" />}
      />
      {isWatchingOnly ? (
        <KeyBlueButton
          disabled={getIsValid && !getIsValid()}
          onClick={onPurchaseTickets}>
          {purchaseLabel()}
        </KeyBlueButton>
      ) : getRunningIndicator ? (
        <Tooltip
          text={
            <T
              id="tickets.purchase-legacy.running"
              m="Privacy Mixer or Autobuyer running, please shut them off before purchasing tickets."
            />
          }>
          <PassphraseModalButton
            disabled={true}
            buttonLabel={purchaseLabel()}
          />
        </Tooltip>
      ) : (
        <KeyBlueButton
          modalTitle={
            <T
              id="tickets.purchaseConfirmation.legacy"
              m="Ticket Purchase Confirmation"
            />
          }
          disabled={getIsValid && !getIsValid()}
          onSubmit={onPurchaseTickets}
          buttonLabel={purchaseLabel()}
        />
      )}

  </>
);

export default PurchaseTicketsForm;
<commit_msg>add the missing label (#3258)<commit_after>import {
  TicketsCogs,
  PassphraseModalButton,
  ImportScriptIconButton,
  KeyBlueButton,
  InvisibleConfirmModalButton
} from "buttons";
import { AccountsSelect, NumTicketsInput } from "inputs";
import { FormattedMessage as T } from "react-intl";
import {
  TransitionMotionWrapper,
  ShowWarning,
  ExternalLink,
  Balance,
  Tooltip
} from "shared";

import "style/StakePool.less";

const purchaseLabel = () => (
  <T id="purchas.legacypurchaseTickets.purchaseBtn" m="Purchase" />
);

const PurchaseTicketsForm = ({
  isShowingAdvanced,
  getQuickBarComponent,
  getAdvancedComponent,
  getIsValid,
  handleOnKeyDown,
  numTicketsToBuy,
  onIncrementNumTickets,
  onDecrementNumTickets,
  onChangeNumTickets,
  onChangeAccount,
  onPurchaseTickets,
  onRevokeTickets,
  onToggleShowAdvanced,
  account,
  ticketPrice,
  willEnter,
  willLeave,
  toggleShowVsp,
  dismissBackupRedeemScript,
  onDismissBackupRedeemScript,
  isWatchingOnly,
  notMixedAccounts,
  getRunningIndicator
}) => (
  <>

          <T id="purchaseTickets.accountFrom.legacy" m="From" />:

        <AccountsSelect
          className="stakepool-purchase-ticket-input-select"
          filterAccounts={notMixedAccounts}
          {...{ account, onChange: onChangeAccount }}
        />

          <T id="purchaseTickets.ticketAmount.legacy" m="Amount" />:

        <NumTicketsInput
          required
          invalid={!getIsValid()}
          invalidMessage={
            <T
              id="purchaseTickets.errors.insufficientBalance.legacy"
              m="Not enough funds"
            />
          }
          numTickets={numTicketsToBuy}
          incrementNumTickets={onIncrementNumTickets}
          decrementNumTickets={onDecrementNumTickets}
          onChangeNumTickets={onChangeNumTickets}
          onKeyDown={handleOnKeyDown}
          showErrors={true}></NumTicketsInput>
        {getIsValid() && (

            <T
              id="purchaseTickets.validMsg.legacy"
              m="Total: {amount} Remaining: {remaining}"
              values={{
                amount: <Balance flat amount={numTicketsToBuy * ticketPrice} />,
                remaining: (
                  <Balance
                    flat
                    amount={account.spendable - numTicketsToBuy * ticketPrice}
                  />
                )
              }}
            />

        )}

        <TicketsCogs
          opened={!isShowingAdvanced}
          onClick={onToggleShowAdvanced}
        />
        <ImportScriptIconButton />

      <TransitionMotionWrapper
        {...{
          styles: !isShowingAdvanced
            ? getQuickBarComponent
            : getAdvancedComponent,
          willEnter: !isShowingAdvanced
            ? () => willEnter(270)
            : () => willEnter(80),
          willLeave
        }}
      />

    {!dismissBackupRedeemScript && (

        <ShowWarning
          warn={
            <T
              id="purchase.ticket.backup.redeem.warn"
              m="You must backup your redeem script. More information about it can be found at {link}"
              values={{
                link: (
                  <ExternalLink
                    href={
                      "https://docs.decred.org/wallets/decrediton/using-decrediton/#backup-redeem-script"
                    }>
                    <T id="purchase.ticket.decred.docs" m="Decred docs" />
                  </ExternalLink>
                )
              }}
            />
          }
        />

          <InvisibleConfirmModalButton
            modalTitle={<T id="purchase.ticket.modal.title" m="Dismiss" />}
            modalContent={
              <T
                id="purchase.ticket.modal.desc"
                m="Are you sure you want to dismiss this message? Make sure your redeem scripts are backed up."
              />
            }
            buttonLabel={
              <T id="purchase.ticket.dismiss.warn" m="Dismiss Message" />
            }
            onSubmit={() => onDismissBackupRedeemScript()}
            className="stakepool-content-send"
          />
          <KeyBlueButton
            className="vsp-warning-backup-redeem-button"
            onClick={() => toggleShowVsp(true)}>
            <T id="purchase.ticket.warn.button" m="Backup Redeem Scripts" />
          </KeyBlueButton>

    )}

      <PassphraseModalButton
        modalTitle={
          <T
            id="tickets.revokeConfirmations.legacy"
            m="Revoke Tickets Confirmation"
          />
        }
        className="stakepool-content-revoke-button"
        onSubmit={onRevokeTickets}
        buttonLabel={<T id="purchaseTickets.revokeBtn.legacy" m="Revoke" />}
      />
      {isWatchingOnly ? (
        <KeyBlueButton
          disabled={getIsValid && !getIsValid()}
          onClick={onPurchaseTickets}>
          {purchaseLabel()}
        </KeyBlueButton>
      ) : getRunningIndicator ? (
        <Tooltip
          text={
            <T
              id="tickets.purchase-legacy.running"
              m="Privacy Mixer or Autobuyer running, please shut them off before purchasing tickets."
            />
          }>
          <PassphraseModalButton
            disabled={true}
            buttonLabel={purchaseLabel()}
          />
        </Tooltip>
      ) : (
        <KeyBlueButton
          modalTitle={
            <T
              id="tickets.purchaseConfirmation.legacy"
              m="Ticket Purchase Confirmation"
            />
          }
          disabled={getIsValid && !getIsValid()}
          onSubmit={onPurchaseTickets}>
          {purchaseLabel()}
        </KeyBlueButton>
      )}

  </>
);

export default PurchaseTicketsForm;
<|endoftext|>


<commit_before>var fs = require('fs')

var OTHERS = parseInt('0001', 8)
var GROUP = parseInt('0010', 8)
var USER = parseInt('0100', 8)

module.exports = function (path, cb) {
  fs.stat(path, function (er, stats) {
    if (er) return cb(er)
    cb(er,
      stats.mode & OTHERS ||
      (stats.mode & GROUP && process.getgid() === stats.gid) ||
      (stats.mode & USER && process.getuid() === stats.uid)
    )
  })
}
<commit_msg>Change the executable check—hopefully work w/linux<commit_after>var fs = require('fs')

module.exports = function (path, cb) {
  fs.stat(path, function (er, stats) {
    var mode = stats.mode

    var owner = mode >> 6
    var group = (mode << 3) >> 6
    var others = (mode << 6) >> 6

    if (er) return cb(er)
    cb(er, !!(owner & 1) || !!(group & 1) || !!(others & 1))
  })
}
<|endoftext|>


<commit_before>angular.module('angularSlideables', [])

.directive('slideable', function () {
    return {
        restrict:'C',
        transclude: true,
        scope: false,
        template: '

',
        link:function (scope, element, attrs) {
            // default properties
                attrs.duration = (!attrs.duration) ? '1s' : attrs.duration;
                attrs.easing = (!attrs.easing) ? 'ease-in-out' : attrs.easing;
            element.css({
                'overflow' : 'hidden',
                'height' : '0px',
                'transitionProperty' : 'height',
                'transitionDuration' : attrs.duration,
                'transitionTimingFunction' : attrs.easing
            }).addClass('contracted');

            var expanded = false;
            scope.$on('slideToggle', function(e, data) {
                if(data.id == attrs.id) {
                    if(!expanded) {
                        var content = element.find('div')[0];
                        content.style.border = '1px solid rgba(0,0,0,0)';
                        var y = content.clientHeight;
                        content.style.border = '0px';
                        element.css('height', y + 'px').addClass('expanded').removeClass('contracted');
                    } else {
                        element.css('height', '0px').removeClass('expanded').addClass('contracted');
                    }
                    expanded = !expanded;
                }
            });
        }
    };
})

.directive('slideToggle', ['$rootScope', function($rootScope) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            attrs.expanded = false;
            element.bind('click', function() {
                $rootScope.$broadcast( 'slideToggle', {id: attrs.slideToggle} );
            });
        }
    }
}]);

<commit_msg>legacy webkit transition support<commit_after>angular.module('angularSlideables', [])

.directive('slideable', function () {
    return {
        restrict:'C',
        transclude: true,
        scope: false,
        template: '

',
        link:function (scope, element, attrs) {
            // default properties
                attrs.duration = (!attrs.duration) ? '1s' : attrs.duration;
                attrs.easing = (!attrs.easing) ? 'ease-in-out' : attrs.easing;
            element.css({
                'overflow' : 'hidden',
                'height' : '0px',
                'transitionProperty' : 'height',
                'transitionDuration' : attrs.duration,
                'transitionTimingFunction' : attrs.easing,
                'webkitTransitionProperty' : 'height',
                'webkitTransitionDuration' : attrs.duration,
                'webkitTransitionTimingFunction' : attrs.easing,
            }).addClass('contracted');

            var expanded = false;
            scope.$on('slideToggle', function(e, data) {
                if(data.id == attrs.id) {
                    if(!expanded) {
                        var content = element.find('div')[0];
                        content.style.border = '1px solid rgba(0,0,0,0)';
                        var y = content.clientHeight;
                        content.style.border = '0px';
                        element.css('height', y + 'px').addClass('expanded').removeClass('contracted');
                    } else {
                        element.css('height', '0px').removeClass('expanded').addClass('contracted');
                    }
                    expanded = !expanded;
                }
            });
        }
    };
})

.directive('slideToggle', ['$rootScope', function($rootScope) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            attrs.expanded = false;
            element.bind('click', function() {
                $rootScope.$broadcast( 'slideToggle', {id: attrs.slideToggle} );
            });
        }
    }
}]);

<|endoftext|>


<commit_before>var _ = require('lodash'),
  references = require('./references');

/**
 * expand fields array
 * @param {array} fields
 * @param {object} componentData
 * @returns {array} expanded
 */
function expandFields(fields, componentData) {
  if (!_.isArray(fields)) {
    throw new Error('Please provide an array of fields!');
  }

  return _.map(fields, function (field) {
    var expanded = {
      field: field,
      data: _.get(componentData, field)
    };

    if (!expanded.data) {
      throw new Error('Field (' + field + ') doesn\'t exist in the schema!');
    }

    return expanded;
  });
}

/**
 * get only the fields with _display: settings
 * @param {object} componentData
 * @returns {array}
 */
function getSettingsGroup(componentData) {
  if (!_.isObject(componentData) || _.isEmpty(componentData)) {
    return [];
  }

  return _.reduce(componentData, function (fields, fieldData, fieldName) {
    if (fieldData._schema && fieldData._schema[references.displayProperty] === 'settings') {
      fields.push({
        field: fieldName,
        data: fieldData
      });
    }

    return fields;
  }, []);
}

module.exports.expandFields = expandFields;
module.exports.getSettingsGroup = getSettingsGroup;
<commit_msg>first pass of groups.get<commit_after>var _ = require('lodash'),
  references = require('./references');

/**
 * expand fields array
 * @param {array} fields
 * @param {object} componentData
 * @returns {array} expanded
 */
function expandFields(fields, componentData) {
  if (!_.isArray(fields)) {
    throw new Error('Please provide an array of fields!');
  }

  return _.map(fields, function (field) {
    var expanded = {
      field: field,
      data: _.get(componentData, field)
    };

    if (!expanded.data) {
      throw new Error('Field (' + field + ') doesn\'t exist in the schema!');
    }

    return expanded;
  });
}

/**
 * get only the fields with _display: settings
 * @param {object} componentData
 * @returns {array}
 */
function getSettingsGroup(componentData) {
  if (!_.isObject(componentData) || _.isEmpty(componentData)) {
    return [];
  }

  return _.reduce(componentData, function (fields, fieldData, fieldName) {
    if (fieldData._schema && fieldData._schema[references.displayProperty] === 'settings') {
      fields.push({
        field: fieldName,
        data: fieldData
      });
    }

    return fields;
  }, []);
}

function get(ref, data, path) {
  var field = _.get(data, path),
    group = data[references.groupsProperty] && _.get(data[references.groupsProperty], path);

  if (field) {
    // simply return the field
    return [{
      field: path,
      data: field
    }];
  } else if (group) {
    // return the expanded group
    return expandFields(_.get(data[references.groupsProperty], path).fields, data);
  } else {
    throw new Error('No group or field found at "' + path + '"');
  }
}

module.exports.expandFields = expandFields;
module.exports.getSettingsGroup = getSettingsGroup;
module.exports.get = get;
<|endoftext|>


<commit_before>'use strict';

const upath = require('upath');
const symbols = require('./symbols');
const Metadata = require('../util/meta');
const lifeycle = require('./decorators/lifecycle');

const sInit = Symbol.for('_init');

/**
 * Provides Ravel with a simple mechanism of registering
 * user-defined modules and connecting them, via
 * injector.js, with dependency injection
 */
class Module {
  /**
   * ## Lifecycle decorators
   */
  /**
   * Methods decorated with `@postinit` will fire after Ravel.init()
   * @example
   *   const Module = require('ravel').Module;
   *   const postinit = Module.postinit;
   *   class MyModule extends Module {
   *     @postinit
   *     doSomething() {
   *       //...
   *     }
   *   }
   */
  static get postinit() { return lifeycle.postinit; }

  /**
   * Methods decorated with `@prelisten` will fire at the beginning of Ravel.listen()
   * @example
   *   const Module = require('ravel').Module;
   *   const prelisten = Module.prelisten;
   *   class MyModule extends Module {
   *     @prelisten
   *     doSomething() {
   *       //...
   *     }
   *   }
   */
  static get prelisten() { return lifeycle.prelisten; }

  /**
   * Methods decorated with `@postlisten` will fire at the end of Ravel.listen()
   * @example
   *   const Module = require('ravel').Module;
   *   const postlisten = Module.postlisten;
   *   class MyModule extends Module {
   *     @postlisten
   *     doSomething() {
   *       //...
   *     }
   *   }
   */
  static get postlisten() { return lifeycle.postlisten; }

  /**
   * Methods decorated with `@preclose` will fire at the beginning of Ravel.close()
   * @example
   *   const Module = require('ravel').Module;
   *   const preclose = Module.preclose;
   *   class MyModule extends Module {
   *     @preclose
   *     doSomething() {
   *       //...
   *     }
   *   }
   */
  static get preclose() { return lifeycle.preclose; }

  /**
   * A reference to the ravel instance with which this Module is registered
   */
  get app() {
    return Metadata.getClassMetaValue(Object.getPrototypeOf(this), 'ravel', 'instance');
  }

  /**
   * The injection name for this module
   */
  get name() { return Metadata.getClassMetaValue(Object.getPrototypeOf(this), 'source', 'name'); }

  /**
   * Ravel's pre-packaged error types
   */
  get ApplicationError() {
    return this.app.ApplicationError;
  }

  /**
   * The logger for this `Module`. Will log messages prefixed with the `Module` name.
   */
  get log() {
    return this.app.log.getLogger(this.name);
  }

  /**
   * The active Ravel key-value store connection (redis).
   * See [util/kvstore](../util/kvstore.js.html) for more information.
   */
  get kvstore() {
    return this.app.kvstore;
  }

  /**
   * An Object with a get() method, which allows easy access to ravel.get()
   * See [core/params](params.js.html) for more information.
   * @example
   *   this.params.get('some ravel parameter');
   */
  get params() {
    const ravelInstance = this.app;
    return {
      get: ravelInstance.get.bind(ravelInstance)
    };
  }

  /**
   * An Object with a scoped() method, which allows easy access to ravel.db.scoped()
   * See [db/database](../db/database.js.html) for more information.
   * @example
   *   this.db.scoped('mysql', function*() {
   *     // this.mysql will be an open database connection
   *   });
   */
  get db() {
    const ravelInstance = this.app;
    return {
      scoped: function(gen) {
        return ravelInstance.db.scoped.bind(ravelInstance.db)(gen);
      }
    };
  }
}

/**
 * Initializer for this `Module`
 * @api private
 */
Module.prototype[sInit] = function(ravelInstance) {
  // connect any Ravel lifecycle handlers to the appropriate events
  const self = this;
  function connectHandlers(decorator, event) {
    const handlers = Metadata.getClassMeta(Object.getPrototypeOf(self), decorator, Object.create(null));
    for (let f of Object.keys(handlers)) {
      ravelInstance.once(event, handlers[f].bind(self));
    }
  }
  connectHandlers('@postinit', 'post init');
  connectHandlers('@prelisten', 'pre listen');
  connectHandlers('@postlisten', 'post listen');
  connectHandlers('@preclose', 'end');
};

/**
 * add in `@authconfig` decorator as static property
 * See [auth/authconfig](../auth/authconfig.js.html) for more information.
 * @example
 *   const Module = require('ravel').Module;
 *   const authconfig = Module.authconfig;
 *
 *   @authconfig
 *   class MyAuthConfigModule extends Module {}
 *
 */
require('../auth/decorators/authconfig')(Module);

/*!
 * Populate `Ravel` class with `app.module` method.
 * @external Ravel
 */
module.exports = function(Ravel) {

  /**
   * Register a module with Ravel
   *
   * A module is a pure node.js javascript class consisting of functions with no
   * network-related functionality, suitable for unit-testing.
   *
   * Modules should use injection to refer to other Ravel modules and NPM
   * dependencies.
   *
   * @memberof Ravel
   * @param {String} modulePath The path to the module
   * @param {String} name the name for the module, which will be used for dependency injection
   * @example
   *   app.module('./modules/mymodule', 'mymodule');
   */
  Ravel.prototype.module = function(modulePath, name) {
    if (name === undefined) {
      // if no name is supplied, error out
      throw new this.ApplicationError.IllegalValue(`Name required for module at ${modulePath}`);
    } else if (this[symbols.moduleFactories][name]) {
      // if a module with this name has already been regsitered, error out
      throw new this.ApplicationError.DuplicateEntry(
        `Module with name '${name}' has already been registered.`);
    }

    const moduleClass = require(upath.join(this.cwd, modulePath));
    if (moduleClass.prototype instanceof Module) {
      // store reference to this ravel instance in metadata
      Metadata.putClassMeta(moduleClass.prototype, 'ravel', 'instance', this);
      // store name in metadata
      Metadata.putClassMeta(moduleClass.prototype, 'source', 'name', name);
      // store path to module file in metadata
      Metadata.putClassMeta(moduleClass.prototype, 'source', 'path', modulePath);
      // store known module with path as the key, so someone can reflect on the class
      this[symbols.registerClassFunc](modulePath, moduleClass);
      // build injection function
      this[symbols.moduleFactories][name] = () => {
        // perform DI on module factory
        const temp = this[symbols.injector].inject({},moduleClass);
        temp[sInit](this);
        // overwrite uninitialized module with the correct one
        this[symbols.modules][name] = temp;
        return temp;
      };
      this[symbols.moduleFactories][name].moduleName = name;
      this[symbols.moduleFactories][name].dependencies = this[symbols.injector].getDependencies(moduleClass);
      this[symbols.moduleFactories][name].parents = [];
      this[symbols.moduleFactories][name].children = [];
    } else {
      throw new this.ApplicationError.IllegalValue(
        `Module with path ${modulePath} must be a subclass of Ravel.Module`);
    }

    // save uninitialized module to Ravel.modules
    // temporarily, until it is replaced by an
    // instantiated version in _moduleInit
    this[symbols.modules][name] = Object.create(null);
  };

  /**
   * Private module init
   *
   * Performs module initialization, detecting dependency cycles
   * and executing module factories in dependency order in
   * Ravel.init()
   * @memberof Ravel
   * @api private
   */
  Ravel.prototype[symbols.moduleInit] = function() {
    const rootFactories = Object.create(null);

    // build dependency graph
    for (let moduleName of Object.keys(this[symbols.moduleFactories])) {
      const dependencies = this[symbols.moduleFactories][moduleName].dependencies;
      const factoryDeps = [];
      for (let d=0;d<dependencies.length;d++) {
        if (this[symbols.moduleFactories][dependencies[d]] !== undefined) {
          // build two-way edge
          factoryDeps.push(this[symbols.moduleFactories][dependencies[d]]);
          this[symbols.moduleFactories][dependencies[d]].children.push(this[symbols.moduleFactories][moduleName]);
        }
      }
      this[symbols.moduleFactories][moduleName].parents = factoryDeps;

      // If this module has no dependencies on other client module factories,
      // then it is a root node.
      if (this[symbols.moduleFactories][moduleName].parents.length === 0) {
        this[symbols.moduleFactories][moduleName].maxDepth = 0;
        rootFactories[moduleName] = this[symbols.moduleFactories][moduleName];
      }
    }

    // calculate max depth of each factory, then sort by it. detect cyclical dependencies.
    const instantiationOrder = [];
    const visitedMeta = new WeakMap();
    const calcDepth = (moduleFactory, visitedTag, startModule, last) => {
      if (!visitedTag) {
        visitedTag = Math.random();
      }
      if (!startModule) {
        startModule = moduleFactory.moduleName;
      }
      if (visitedMeta.get(moduleFactory) === visitedTag) {
        throw new this.ApplicationError.General(
          `Module instantiation failed. A cyclical dependency exists between modules \' ${startModule} and ${last}`);
      } else if (moduleFactory.maxDepth === undefined) {
        visitedMeta.set(moduleFactory, visitedTag);
        let maxDepth = -1;
        for (let p of moduleFactory.parents) {
          // if (!moduleFactory.parents.hasOwnProperty(p)) {continue;}
          let pDepth = p.maxDepth !== undefined ?
            p.maxDepth :
            calcDepth(p, visitedTag, startModule, moduleFactory.moduleName);
          maxDepth = Math.max(maxDepth, pDepth);
        }
        moduleFactory.maxDepth = maxDepth+1;
      }
      return moduleFactory.maxDepth;
    };
    for (let moduleName of Object.keys(this[symbols.moduleFactories])) {
      const depth = calcDepth(this[symbols.moduleFactories][moduleName]);
      if (!instantiationOrder[depth]) {
        instantiationOrder[depth] = [];
      }
      instantiationOrder[depth].push(this[symbols.moduleFactories][moduleName]);
    }

    // instantiate in depth order
    for (let currDepth=0;currDepth<instantiationOrder.length;currDepth++) {
      for (let m=0;m<instantiationOrder[currDepth].length;m++) {
        instantiationOrder[currDepth][m]();
      }
    }
  };
};

/**
 * Export Module class
 */
module.exports.Module = Module;
<commit_msg>Improving docs for Ravel.Module<commit_after>'use strict';

const upath = require('upath');
const symbols = require('./symbols');
const Metadata = require('../util/meta');
const lifeycle = require('./decorators/lifecycle');

const sInit = Symbol.for('_init');

/**
 * `Module`s are plain old node.js modules exporting a single class which encapsulates
 * application logic. `Module`s support dependency injection of core Ravel services and
 * other Modules alongside npm dependencies *(no relative `require`'s!)*.
 *
 * `Module`s are instantiated safely in dependency-order, and cyclical
 * dependencies are detected automatically.
 *
 * @example
 *   const inject = require('ravel').inject;
 *   const Module = require('ravel').Module;
 *   const postinit = Module.postinit;
 *
 *   @inject('path', 'fs', 'custom-module')
 *   class MyModule extends Module {
 *     constructor(path, fs, custom) {
 *       super();
 *       this.path = path;
 *       this.fs = fs;
 *       this.custom = custom;
 *     }
 *
 *     aMethod() {
 *       //...
 *     }
 *   }
 */
class Module {
  /**
   * ## Lifecycle decorators
   */
  /**
   * Methods decorated with `@postinit` will fire after Ravel.init()
   * @example
   *   const Module = require('ravel').Module;
   *   const postinit = Module.postinit;
   *   class MyModule extends Module {
   *     @postinit
   *     doSomething() {
   *       //...
   *     }
   *   }
   */
  static get postinit() { return lifeycle.postinit; }

  /**
   * Methods decorated with `@prelisten` will fire at the beginning of Ravel.listen()
   * @example
   *   const Module = require('ravel').Module;
   *   const prelisten = Module.prelisten;
   *   class MyModule extends Module {
   *     @prelisten
   *     doSomething() {
   *       //...
   *     }
   *   }
   */
  static get prelisten() { return lifeycle.prelisten; }

  /**
   * Methods decorated with `@postlisten` will fire at the end of Ravel.listen()
   * @example
   *   const Module = require('ravel').Module;
   *   const postlisten = Module.postlisten;
   *   class MyModule extends Module {
   *     @postlisten
   *     doSomething() {
   *       //...
   *     }
   *   }
   */
  static get postlisten() { return lifeycle.postlisten; }

  /**
   * Methods decorated with `@preclose` will fire at the beginning of Ravel.close()
   * @example
   *   const Module = require('ravel').Module;
   *   const preclose = Module.preclose;
   *   class MyModule extends Module {
   *     @preclose
   *     doSomething() {
   *       //...
   *     }
   *   }
   */
  static get preclose() { return lifeycle.preclose; }

  /**
   * A reference to the ravel instance with which this Module is registered
   */
  get app() {
    return Metadata.getClassMetaValue(Object.getPrototypeOf(this), 'ravel', 'instance');
  }

  /**
   * The injection name for this module
   */
  get name() { return Metadata.getClassMetaValue(Object.getPrototypeOf(this), 'source', 'name'); }

  /**
   * Ravel's pre-packaged error types
   */
  get ApplicationError() {
    return this.app.ApplicationError;
  }

  /**
   * The logger for this `Module`. Will log messages prefixed with the `Module` name.
   */
  get log() {
    return this.app.log.getLogger(this.name);
  }

  /**
   * The active Ravel key-value store connection (redis).
   * See [util/kvstore](../util/kvstore.js.html) for more information.
   */
  get kvstore() {
    return this.app.kvstore;
  }

  /**
   * An Object with a get() method, which allows easy access to ravel.get()
   * See [core/params](params.js.html) for more information.
   * @example
   *   this.params.get('some ravel parameter');
   */
  get params() {
    const ravelInstance = this.app;
    return {
      get: ravelInstance.get.bind(ravelInstance)
    };
  }

  /**
   * An Object with a scoped() method, which allows easy access to ravel.db.scoped()
   * See [db/database](../db/database.js.html) for more information.
   * @example
   *   this.db.scoped('mysql', function*() {
   *     // this.mysql will be an open database connection
   *   });
   */
  get db() {
    const ravelInstance = this.app;
    return {
      scoped: function(gen) {
        return ravelInstance.db.scoped.bind(ravelInstance.db)(gen);
      }
    };
  }
}

/**
 * Initializer for this `Module`
 * @api private
 */
Module.prototype[sInit] = function(ravelInstance) {
  // connect any Ravel lifecycle handlers to the appropriate events
  const self = this;
  function connectHandlers(decorator, event) {
    const handlers = Metadata.getClassMeta(Object.getPrototypeOf(self), decorator, Object.create(null));
    for (let f of Object.keys(handlers)) {
      ravelInstance.once(event, handlers[f].bind(self));
    }
  }
  connectHandlers('@postinit', 'post init');
  connectHandlers('@prelisten', 'pre listen');
  connectHandlers('@postlisten', 'post listen');
  connectHandlers('@preclose', 'end');
};

/**
 * add in `@authconfig` decorator as static property
 * See [auth/authconfig](../auth/authconfig.js.html) for more information.
 * @example
 *   const Module = require('ravel').Module;
 *   const authconfig = Module.authconfig;
 *
 *   @authconfig
 *   class MyAuthConfigModule extends Module {}
 *
 */
require('../auth/decorators/authconfig')(Module);

/*!
 * Populate `Ravel` class with `app.module` method.
 * @external Ravel
 */
module.exports = function(Ravel) {

  /**
   * Register a module with Ravel
   *
   * A module is a pure node.js javascript class consisting of functions with no
   * network-related functionality, suitable for unit-testing.
   *
   * Modules should use injection to refer to other Ravel modules and NPM
   * dependencies.
   *
   * @memberof Ravel
   * @param {String} modulePath The path to the module
   * @param {String} name the name for the module, which will be used for dependency injection
   * @example
   *   app.module('./modules/mymodule', 'mymodule');
   */
  Ravel.prototype.module = function(modulePath, name) {
    if (name === undefined) {
      // if no name is supplied, error out
      throw new this.ApplicationError.IllegalValue(`Name required for module at ${modulePath}`);
    } else if (this[symbols.moduleFactories][name]) {
      // if a module with this name has already been regsitered, error out
      throw new this.ApplicationError.DuplicateEntry(
        `Module with name '${name}' has already been registered.`);
    }

    const moduleClass = require(upath.join(this.cwd, modulePath));
    if (moduleClass.prototype instanceof Module) {
      // store reference to this ravel instance in metadata
      Metadata.putClassMeta(moduleClass.prototype, 'ravel', 'instance', this);
      // store name in metadata
      Metadata.putClassMeta(moduleClass.prototype, 'source', 'name', name);
      // store path to module file in metadata
      Metadata.putClassMeta(moduleClass.prototype, 'source', 'path', modulePath);
      // store known module with path as the key, so someone can reflect on the class
      this[symbols.registerClassFunc](modulePath, moduleClass);
      // build injection function
      this[symbols.moduleFactories][name] = () => {
        // perform DI on module factory
        const temp = this[symbols.injector].inject({},moduleClass);
        temp[sInit](this);
        // overwrite uninitialized module with the correct one
        this[symbols.modules][name] = temp;
        return temp;
      };
      this[symbols.moduleFactories][name].moduleName = name;
      this[symbols.moduleFactories][name].dependencies = this[symbols.injector].getDependencies(moduleClass);
      this[symbols.moduleFactories][name].parents = [];
      this[symbols.moduleFactories][name].children = [];
    } else {
      throw new this.ApplicationError.IllegalValue(
        `Module with path ${modulePath} must be a subclass of Ravel.Module`);
    }

    // save uninitialized module to Ravel.modules
    // temporarily, until it is replaced by an
    // instantiated version in _moduleInit
    this[symbols.modules][name] = Object.create(null);
  };

  /**
   * Private module init
   *
   * Performs module initialization, detecting dependency cycles
   * and executing module factories in dependency order in
   * Ravel.init()
   * @memberof Ravel
   * @api private
   */
  Ravel.prototype[symbols.moduleInit] = function() {
    const rootFactories = Object.create(null);

    // build dependency graph
    for (let moduleName of Object.keys(this[symbols.moduleFactories])) {
      const dependencies = this[symbols.moduleFactories][moduleName].dependencies;
      const factoryDeps = [];
      for (let d=0;d<dependencies.length;d++) {
        if (this[symbols.moduleFactories][dependencies[d]] !== undefined) {
          // build two-way edge
          factoryDeps.push(this[symbols.moduleFactories][dependencies[d]]);
          this[symbols.moduleFactories][dependencies[d]].children.push(this[symbols.moduleFactories][moduleName]);
        }
      }
      this[symbols.moduleFactories][moduleName].parents = factoryDeps;

      // If this module has no dependencies on other client module factories,
      // then it is a root node.
      if (this[symbols.moduleFactories][moduleName].parents.length === 0) {
        this[symbols.moduleFactories][moduleName].maxDepth = 0;
        rootFactories[moduleName] = this[symbols.moduleFactories][moduleName];
      }
    }

    // calculate max depth of each factory, then sort by it. detect cyclical dependencies.
    const instantiationOrder = [];
    const visitedMeta = new WeakMap();
    const calcDepth = (moduleFactory, visitedTag, startModule, last) => {
      if (!visitedTag) {
        visitedTag = Math.random();
      }
      if (!startModule) {
        startModule = moduleFactory.moduleName;
      }
      if (visitedMeta.get(moduleFactory) === visitedTag) {
        throw new this.ApplicationError.General(
          `Module instantiation failed. A cyclical dependency exists between modules \' ${startModule} and ${last}`);
      } else if (moduleFactory.maxDepth === undefined) {
        visitedMeta.set(moduleFactory, visitedTag);
        let maxDepth = -1;
        for (let p of moduleFactory.parents) {
          // if (!moduleFactory.parents.hasOwnProperty(p)) {continue;}
          let pDepth = p.maxDepth !== undefined ?
            p.maxDepth :
            calcDepth(p, visitedTag, startModule, moduleFactory.moduleName);
          maxDepth = Math.max(maxDepth, pDepth);
        }
        moduleFactory.maxDepth = maxDepth+1;
      }
      return moduleFactory.maxDepth;
    };
    for (let moduleName of Object.keys(this[symbols.moduleFactories])) {
      const depth = calcDepth(this[symbols.moduleFactories][moduleName]);
      if (!instantiationOrder[depth]) {
        instantiationOrder[depth] = [];
      }
      instantiationOrder[depth].push(this[symbols.moduleFactories][moduleName]);
    }

    // instantiate in depth order
    for (let currDepth=0;currDepth<instantiationOrder.length;currDepth++) {
      for (let m=0;m<instantiationOrder[currDepth].length;m++) {
        instantiationOrder[currDepth][m]();
      }
    }
  };
};

/**
 * Export Module class
 */
module.exports.Module = Module;
<|endoftext|>


<commit_before>var module = angular.module('fittext', []);

module.directive('fittext', [ '$window', function( $window ) {
	return {
		restrict: 'A',
		scope: true,
		link: function( $scope, $element, $attrs ) {
			$scope.compressor = $attrs.compressor || 1;
			$scope.minFontSize = $attrs.min || Number.NEGATIVE_INFINITY;
			$scope.maxFontSize = $attrs.max || Number.POSITIVE_INFINITY;

			var resizer = function() {
				$scope.fontSize = Math.max(
					Math.min(
						$element.width() / ( $scope.compressor*10 ),
						parseFloat( $scope.maxFontSize )
					),
					parseFloat( $scope.minFontSize )
				);
			};

			var readyStateCheckInterval = setInterval( function() {
				if ( document.readyState === "complete" ) {
					clearInterval( readyStateCheckInterval );
					$scope.$apply( function() {
						resizer();
					});
				}
			}, 10);

			angular.element( $window ).bind( 'resize', function() {
				$scope.$apply( function() {
					resizer();
				});
			});

		}
	}
}]);<commit_msg>Improved $apply call<commit_after>var module = angular.module('fittext', []);

module.directive('fittext', [ '$window', function( $window ) {
	return {
		restrict: 'A',
		scope: true,
		link: function( $scope, $element, $attrs ) {
			$scope.compressor = $attrs.compressor || 1;
			$scope.minFontSize = $attrs.min || Number.NEGATIVE_INFINITY;
			$scope.maxFontSize = $attrs.max || Number.POSITIVE_INFINITY;

			var resizer = function() {
				$scope.$apply( function() {
					$scope.fontSize = Math.max(
						Math.min(
							$element.width() / ( $scope.compressor * 10 ),
							parseFloat( $scope.maxFontSize )
						),
						parseFloat( $scope.minFontSize )
					);
				});
			};

			var readyStateCheckInterval = setInterval( function() {
				if ( document.readyState === "complete" ) {
					clearInterval( readyStateCheckInterval );
					resizer();
				}
			}, 10);

			angular.element( $window ).bind( 'resize', function() {
				resizer();
			});

		}
	}
}]);<|endoftext|>


<commit_before>import {PromiseBackend} from '../node_modules/deferred/src/PromiseMock';
import {Pipeline} from '../src/pipeline';

describe('Pipeline', () => {
  PromiseBackend.setGlobal(window);
  PromiseBackend.patchWithMock();

  it('should run even when there are not steps', () => {
    var pipeline = new Pipeline();
    var context = {};
    var resolved = false;

    pipeline.run(context).then((result) => {
      expect(result.completed).toBe(true);
    });

    PromiseBackend.flush(true);
  });
});
<commit_msg>test: improve pipeline test<commit_after>import {PromiseBackend} from '../node_modules/deferred/src/PromiseMock';
import {Pipeline} from '../src/pipeline';

describe('Pipeline', () => {
  PromiseBackend.setGlobal(window);
  PromiseBackend.patchWithMock();

  var pipeline,
      spy,
      context;

  beforeEach(() => {
    context = {};
    pipeline = new Pipeline();
  });

  it('should run even when there are not steps', () => {
    pipeline.run(context).then((result) => {
      expect(result.completed).toBe(true);
    });

    PromiseBackend.flush(true);
  });

  it('should pass the context to the step', () => {
    var step = mockStep();
    pipeline.withStep(step);
    pipeline.run(context).then((result) => {
      expect(result.completed).toBe(true);
    });

    expect(step.spy).toHaveBeenCalledWith(context);
  });

  it('should set the context to incomplete if a step cancels', () => {
    pipeline.withStep((context) => context.cancel()).
    run(context).catch((result) => {
      expect(result.completed).toBe(false);
      expect(result.status).toBe('rejected');
    });

    PromiseBackend.flush(true);
  });

  it('should set the context to incomplete if a step throws', () => {
    pipeline.withStep(() => {
      throw new Error('oops');
    }).
    run(context).catch((result) => {
      expect(result.completed).toBe(false);
      expect(result.status).toBe('rejected');
    });

    PromiseBackend.flush(true);
  });

  it('should delegate to the next step if the previous one cancels', () => {
    var firstStep = false;

    pipeline.
      withStep((context) => {
        firstStep = true;
        return context.next();
      }).
      withStep((context) => context.complete()).
      run(context).then((result) => {
        expect(firstStep).toBe(true);
        expect(result.completed).toBe(true);
        expect(result.status).toBe('completed');
      });

    PromiseBackend.flush(true);
  });

  function mockStep (name) {
    var spy = jasmine.createSpy(name ? (name + ' step') : 'step');
    return {
      run: (ctx) => {
        spy(ctx);
        return Promise.resolve();
      },
      name: name,
      spy: spy
    };
  }
});
<|endoftext|>


<commit_before>import assert from 'assert'

import {Presence} from '../src/index.js'
import {Map, fromJS} from 'immutable'

let clone = (obj) => { return JSON.parse(JSON.stringify(obj)) }

const assertImmutableEquals = (expected, actual) => {
  // Test using Immutables equals method
  if (!expected.equals(actual)) {
    // Produce readable diffs
    assert.deepEqual(expected.toJS(), actual.toJS())
    // failsafe, if toJS somehow was equals
    assert(expected.equals(actual))
  }
}
let fixtures = {
  joins () {
    return {u1: {metas: [{id: 1, phx_ref: '1.2'}]}}
  },
  leaves () {
    return {u2: {metas: [{id: 2, phx_ref: '2'}]}}
  },
  state () {
    return fromJS({
      u1: {metas: [{id: 1, phx_ref: '1'}]},
      u2: {metas: [{id: 2, phx_ref: '2'}]},
      u3: {metas: [{id: 3, phx_ref: '3'}]}
    })
  }
}

describe('syncState', () => {
  it('syncs empty state', () => {
    const newStateData = {u1: {metas: [{id: 1, phx_ref: '1'}]}}
    const state = new Map()
    const newState = Presence.syncState(state, newStateData)
    assert.deepEqual(state, new Map())
    assertImmutableEquals(fromJS(newStateData), newState)
  })

  it("onJoins new presences and onLeave's left presences", () => {
    const newState = fixtures.state()
    const state = fromJS({u4: {metas: [{id: 4, phx_ref: '4'}]}})
    let joined = {}
    let left = {}
    const onJoin = (key, current, newPres) => {
      joined[key] = {current: current && current.toJS(), newPres: newPres.toJS()}
    }
    const onLeave = (key, current, leftPres) => {
      left[key] = {current: current && current.toJS(), leftPres: leftPres.toJS()}
    }
    const syncedState = Presence.syncState(state, newState, onJoin, onLeave)
    assertImmutableEquals(newState, syncedState)
    assert.deepEqual(joined, {
      u1: {current: null, newPres: {metas: [{id: 1, phx_ref: '1'}]}},
      u2: {current: null, newPres: {metas: [{id: 2, phx_ref: '2'}]}},
      u3: {current: null, newPres: {metas: [{id: 3, phx_ref: '3'}]}}
    })
    assert.deepEqual(left, {
      u4: {current: {metas: []}, leftPres: {metas: [{id: 4, phx_ref: '4'}]}}
    })
  })

  it('onJoins only newly added metas', () => {
    const newState = fromJS({u3: {metas: [{id: 3, phx_ref: '3'}, {id: 3, phx_ref: '3.new'}]}})
    const state = fromJS({u3: {metas: [{id: 3, phx_ref: '3'}]}})
    const joined = {}
    const left = {}
    const onJoin = (key, current, newPres) => {
      joined[key] = {current: current && current.toJS(), newPres: newPres.toJS()}
    }
    const onLeave = (key, current, leftPres) => {
      left[key] = {current: current && current.toJS(), leftPres: leftPres.toJS()}
    }
    const syncedState = Presence.syncState(state, newState, onJoin, onLeave)
    assertImmutableEquals(newState, syncedState)
    assert.deepEqual(joined, {
      u3: {current: {metas: [{id: 3, phx_ref: '3'}]},
        newPres: {metas: [{id: 3, phx_ref: '3'}, {id: 3, phx_ref: '3.new'}]}}
    })
    assert.deepEqual(left, {})
  })
})

describe('syncDiff', () => {
  it('does nothing without leaves or joins', () => {
    const state = new Map()
    assertImmutableEquals(state, Presence.syncDiff(state, {joins: {}, leaves: {}}))
  })

  it('syncs empty state', () => {
    let joins = {u1: {metas: [{id: 1, phx_ref: '1'}]}}
    assertImmutableEquals(fromJS(joins), Presence.syncDiff(new Map({}), {joins: joins, leaves: {}}))
  })

  it('adds additional meta', () => {
    let state = fixtures.state()
    assertImmutableEquals(
      fromJS({
        u1: {metas: [{id: 1, phx_ref: '1'}, {id: 1, phx_ref: '1.2'}]},
        u2: {metas: [{id: 2, phx_ref: '2'}]},
        u3: {metas: [{id: 3, phx_ref: '3'}]}
      }),
      Presence.syncDiff(state, {joins: fixtures.joins(), leaves: {}})
    )
  })

  it('removes presence when meta is empty and adds additional meta', () => {
    let state = fixtures.state()
    const newState = Presence.syncDiff(state, {joins: fixtures.joins(), leaves: fixtures.leaves()})

    assertImmutableEquals(
      fromJS({
        u1: {metas: [{id: 1, phx_ref: '1'}, {id: 1, phx_ref: '1.2'}]},
        u3: {metas: [{id: 3, phx_ref: '3'}]}
      }),
      newState
    )
  })

  it('removes meta while leaving key if other metas exist', () => {
    const state = fromJS({
      u1: {metas: [{id: 1, phx_ref: '1'}, {id: 1, phx_ref: '1.2'}]}
    })
    const newState = Presence.syncDiff(state, {joins: {}, leaves: {u1: {metas: [{id: 1, phx_ref: '1'}]}}})
    const expected = fromJS({
      u1: {metas: [{id: 1, phx_ref: '1.2'}]}
    })
    assertImmutableEquals(expected, newState)
  })
})

describe('list', () => {
  it('lists full presence by default', () => {
    const state = fixtures.state()
    const expected = fromJS([
      {metas: [{id: 1, phx_ref: '1'}]},
      {metas: [{id: 2, phx_ref: '2'}]},
      {metas: [{id: 3, phx_ref: '3'}]}
    ])
    assertImmutableEquals(expected, Presence.list(state))
  })

  it('lists with custom function', () => {
    let state = fromJS({u1: {metas: [
      {id: 1, phx_ref: '1.first'},
      {id: 1, phx_ref: '1.second'}]
    }})

    assertImmutableEquals(
      fromJS([{id: 1, phx_ref: '1.first'}]),
      Presence.list(state, (_key, value) => value.get('metas').first())
    )
  })
})
<commit_msg>Add test for removed meta on syncState<commit_after>import assert from 'assert'

import {Presence} from '../src/index.js'
import {Map, fromJS} from 'immutable'

let clone = (obj) => { return JSON.parse(JSON.stringify(obj)) }

const assertImmutableEquals = (expected, actual) => {
  // Test using Immutables equals method
  if (!expected.equals(actual)) {
    // Produce readable diffs
    assert.deepEqual(expected.toJS(), actual.toJS())
    // failsafe, if toJS somehow was equals
    assert(expected.equals(actual))
  }
}
let fixtures = {
  joins () {
    return {u1: {metas: [{id: 1, phx_ref: '1.2'}]}}
  },
  leaves () {
    return {u2: {metas: [{id: 2, phx_ref: '2'}]}}
  },
  state () {
    return fromJS({
      u1: {metas: [{id: 1, phx_ref: '1'}]},
      u2: {metas: [{id: 2, phx_ref: '2'}]},
      u3: {metas: [{id: 3, phx_ref: '3'}]}
    })
  }
}

describe('syncState', () => {
  it('syncs empty state', () => {
    const newStateData = {u1: {metas: [{id: 1, phx_ref: '1'}]}}
    const state = new Map()
    const newState = Presence.syncState(state, newStateData)
    assert.deepEqual(state, new Map())
    assertImmutableEquals(fromJS(newStateData), newState)
  })

  it("onJoins new presences and onLeave's left presences", () => {
    const newState = fixtures.state()
    const state = fromJS({u4: {metas: [{id: 4, phx_ref: '4'}]}})
    let joined = {}
    let left = {}
    const onJoin = (key, current, newPres) => {
      joined[key] = {current: current && current.toJS(), newPres: newPres.toJS()}
    }
    const onLeave = (key, current, leftPres) => {
      left[key] = {current: current && current.toJS(), leftPres: leftPres.toJS()}
    }
    const syncedState = Presence.syncState(state, newState, onJoin, onLeave)
    assertImmutableEquals(newState, syncedState)
    assert.deepEqual(joined, {
      u1: {current: null, newPres: {metas: [{id: 1, phx_ref: '1'}]}},
      u2: {current: null, newPres: {metas: [{id: 2, phx_ref: '2'}]}},
      u3: {current: null, newPres: {metas: [{id: 3, phx_ref: '3'}]}}
    })
    assert.deepEqual(left, {
      u4: {current: {metas: []}, leftPres: {metas: [{id: 4, phx_ref: '4'}]}}
    })
  })

  it('onJoins only newly added metas', () => {
    const newState = fromJS({u3: {metas: [{id: 3, phx_ref: '3'}, {id: 3, phx_ref: '3.new'}]}})
    const state = fromJS({u3: {metas: [{id: 3, phx_ref: '3'}, {id: 3, phx_ref: '3.old'}]}})
    const joined = {}
    const left = {}
    const onJoin = (key, current, newPres) => {
      joined[key] = {current: current && current.toJS(), newPres: newPres.toJS()}
    }
    const onLeave = (key, current, leftPres) => {
      left[key] = {current: current && current.toJS(), leftPres: leftPres.toJS()}
    }
    const syncedState = Presence.syncState(state, newState, onJoin, onLeave)
    assertImmutableEquals(newState, syncedState)
    assert.deepEqual({
        u3: {
          current: {metas: [{id: 3, phx_ref: '3'}, {id: 3, phx_ref: '3.old'}]},
          newPres: {metas: [{id: 3, phx_ref: '3'}, {id: 3, phx_ref: '3.old'}, {id: 3, phx_ref: '3.new'}]}
        }
      }, joined)
    assert.deepEqual({
        u3: {
          leftPres: {metas: [{id: 3, phx_ref: '3.old'}]},
          current: {metas: [{id: 3, phx_ref: '3'}, {id: 3, phx_ref: '3.new'}]}
        }
      }, left)
  })
})

describe('syncDiff', () => {
  it('does nothing without leaves or joins', () => {
    const state = new Map()
    assertImmutableEquals(state, Presence.syncDiff(state, {joins: {}, leaves: {}}))
  })

  it('syncs empty state', () => {
    let joins = {u1: {metas: [{id: 1, phx_ref: '1'}]}}
    assertImmutableEquals(fromJS(joins), Presence.syncDiff(new Map({}), {joins: joins, leaves: {}}))
  })

  it('adds additional meta', () => {
    let state = fixtures.state()
    assertImmutableEquals(
      fromJS({
        u1: {metas: [{id: 1, phx_ref: '1'}, {id: 1, phx_ref: '1.2'}]},
        u2: {metas: [{id: 2, phx_ref: '2'}]},
        u3: {metas: [{id: 3, phx_ref: '3'}]}
      }),
      Presence.syncDiff(state, {joins: fixtures.joins(), leaves: {}})
    )
  })

  it('removes presence when meta is empty and adds additional meta', () => {
    let state = fixtures.state()
    const newState = Presence.syncDiff(state, {joins: fixtures.joins(), leaves: fixtures.leaves()})

    assertImmutableEquals(
      fromJS({
        u1: {metas: [{id: 1, phx_ref: '1'}, {id: 1, phx_ref: '1.2'}]},
        u3: {metas: [{id: 3, phx_ref: '3'}]}
      }),
      newState
    )
  })

  it('removes meta while leaving key if other metas exist', () => {
    const state = fromJS({
      u1: {metas: [{id: 1, phx_ref: '1'}, {id: 1, phx_ref: '1.2'}]}
    })
    const newState = Presence.syncDiff(state, {joins: {}, leaves: {u1: {metas: [{id: 1, phx_ref: '1'}]}}})
    const expected = fromJS({
      u1: {metas: [{id: 1, phx_ref: '1.2'}]}
    })
    assertImmutableEquals(expected, newState)
  })
})

describe('list', () => {
  it('lists full presence by default', () => {
    const state = fixtures.state()
    const expected = fromJS([
      {metas: [{id: 1, phx_ref: '1'}]},
      {metas: [{id: 2, phx_ref: '2'}]},
      {metas: [{id: 3, phx_ref: '3'}]}
    ])
    assertImmutableEquals(expected, Presence.list(state))
  })

  it('lists with custom function', () => {
    let state = fromJS({u1: {metas: [
      {id: 1, phx_ref: '1.first'},
      {id: 1, phx_ref: '1.second'}]
    }})

    assertImmutableEquals(
      fromJS([{id: 1, phx_ref: '1.first'}]),
      Presence.list(state, (_key, value) => value.get('metas').first())
    )
  })
})
<|endoftext|>


<commit_before>module('relative-time');

test('rewrites from now past datetime to minutes ago', function() {
  var now = new Date(Date.now() - 3 * 60 * 1000).toISOString();
  var time = document.createElement('time', 'relative-time');
  time.setAttribute('datetime', now);
  equal(time.textContent, '3 minutes ago');
});

test('rewrites a few seconds ago to just now', function() {
  var now = new Date().toISOString();
  var time = document.createElement('time', 'relative-time');
  time.setAttribute('datetime', now);
  equal(time.textContent, 'just now');
});

test('displays future times as just now', function() {
  var now = new Date(Date.now() + 3 * 1000).toISOString();
  var time = document.createElement('time', 'relative-time');
  time.setAttribute('datetime', now);
  equal(time.textContent, 'just now');
});

test('displays a day ago', function() {
  var now = new Date(Date.now() - 60 * 60 * 24 * 1000).toISOString();
  var time = document.createElement('time', 'relative-time');
  time.setAttribute('datetime', now);
  equal(time.textContent, 'a day ago');
});

test('displays 2 days ago', function() {
  var now = new Date(Date.now() - 2 * 60 * 60 * 24 * 1000).toISOString();
  var time = document.createElement('time', 'relative-time');
  time.setAttribute('datetime', now);
  equal(time.textContent, '2 days ago');
});

test('switches to dates after 30 days', function() {
  var now = new Date(Date.now() - 30 * 60 * 60 * 24 * 1000).toISOString();
  var time = document.createElement('time', 'relative-time');
  time.setAttribute('datetime', now);
  ok(time.textContent.match(/on \w\w\w \d{1,2}/));
});

test('ignores malformed dates', function() {
  var time = document.createElement('time', 'relative-time');
  time.textContent = 'Jun 30';
  time.setAttribute('datetime', 'bogus');
  equal(time.textContent, 'Jun 30');
});

test('sets relative contents when parsed element is upgraded', function() {
  var now = new Date().toISOString();
  var root = document.createElement('div');
  root.innerHTML = '<time is="relative-time" datetime="'+now+'"></time>';
  if ('CustomElements' in window) {
    window.CustomElements.upgradeSubtree(root);
  }
  equal(root.children[0].textContent, 'just now');
});
<commit_msg>Add blank date test.<commit_after>module('relative-time');

test('rewrites from now past datetime to minutes ago', function() {
  var now = new Date(Date.now() - 3 * 60 * 1000).toISOString();
  var time = document.createElement('time', 'relative-time');
  time.setAttribute('datetime', now);
  equal(time.textContent, '3 minutes ago');
});

test('rewrites a few seconds ago to just now', function() {
  var now = new Date().toISOString();
  var time = document.createElement('time', 'relative-time');
  time.setAttribute('datetime', now);
  equal(time.textContent, 'just now');
});

test('displays future times as just now', function() {
  var now = new Date(Date.now() + 3 * 1000).toISOString();
  var time = document.createElement('time', 'relative-time');
  time.setAttribute('datetime', now);
  equal(time.textContent, 'just now');
});

test('displays a day ago', function() {
  var now = new Date(Date.now() - 60 * 60 * 24 * 1000).toISOString();
  var time = document.createElement('time', 'relative-time');
  time.setAttribute('datetime', now);
  equal(time.textContent, 'a day ago');
});

test('displays 2 days ago', function() {
  var now = new Date(Date.now() - 2 * 60 * 60 * 24 * 1000).toISOString();
  var time = document.createElement('time', 'relative-time');
  time.setAttribute('datetime', now);
  equal(time.textContent, '2 days ago');
});

test('switches to dates after 30 days', function() {
  var now = new Date(Date.now() - 30 * 60 * 60 * 24 * 1000).toISOString();
  var time = document.createElement('time', 'relative-time');
  time.setAttribute('datetime', now);
  ok(time.textContent.match(/on \w\w\w \d{1,2}/));
});

test('ignores malformed dates', function() {
  var time = document.createElement('time', 'relative-time');
  time.textContent = 'Jun 30';
  time.setAttribute('datetime', 'bogus');
  equal(time.textContent, 'Jun 30');
});

test('ignores blank dates', function() {
  var time = document.createElement('time', 'relative-time');
  time.textContent = 'Jun 30';
  time.setAttribute('datetime', '');
  equal(time.textContent, 'Jun 30');
});
test('sets relative contents when parsed element is upgraded', function() {
  var now = new Date().toISOString();
  var root = document.createElement('div');
  root.innerHTML = '<time is="relative-time" datetime="'+now+'"></time>';
  if ('CustomElements' in window) {
    window.CustomElements.upgradeSubtree(root);
  }
  equal(root.children[0].textContent, 'just now');
});
<|endoftext|>


<commit_before>'use strict';
var _ = require('lodash');

var defaults = {
  messageLimit: false
};
function Storage(options) {
  this.options = _.assign({}, defaults, options);
};

Storage.prototype.all = function all() { throw new Exception("Unimplemented"); };
Storage.prototype.store = function store(message) { throw new Exception("Unimplemented"); };
Storage.prototype.get = function get(id) { throw new Exception("Unimplemented"); };
Storage.prototype.settings = function settings() {
  return this.options;
};

module.exports = Storage;
<commit_msg>javascript is throw error not exception<commit_after>'use strict';
var _ = require('lodash');

var defaults = {
  messageLimit: false
};
function Storage(options) {
  this.options = _.assign({}, defaults, options);
};

Storage.prototype.all = function all() { throw new Error("Unimplemented"); };
Storage.prototype.store = function store(message) { throw new Error("Unimplemented"); };
Storage.prototype.get = function get(id) { throw new Error("Unimplemented"); };
Storage.prototype.settings = function settings() {
  return this.options;
};

module.exports = Storage;
<|endoftext|>


<commit_before>if (Meteor.isServer) {
    // Start a server to test HTTP client streams.
    var http = Npm.require("http");
    var url = Npm.require("url");
    var server = http.createServer(function(req, res) {
        var url = req.url;

        switch (url) {
            case "/test1":
                res.write("OK");
                res.end();
                break;

            case "/test2":
                res.write("1");
                setTimeout(function() { res.write("2"); }, 10);
                setTimeout(function() { res.write("3"); }, 20);
                setTimeout(function() { res.write("4"); }, 30);
                setTimeout(function() { res.write("5"); }, 40);
                setTimeout(function() { res.end(); }, 50);
                break;

            case "/test3":
                var buf1 = new Buffer([1,2,3,4]);
                res.write(buf1);

                setTimeout(function() {
                    var buf2 = new Buffer([5,6,7,8]);
                    res.write(buf2);

                    res.end();
                }, 50);

                break;

            case "/test4":
                var buffers = [];

                req.on("data", function(data) {
                    buffers.push(data);
                });

                req.on("end", function() {
                    res.write(Buffer.concat(buffers));
                    res.end();
                });

                break;

            case "/method":
                res.setHeader("X-METHOD", "HEAD");

                if (req.method !== "HEAD") {
                    res.write(req.method);
                }

                res.end();
                break;

            case "/echo":
                var body = "";

                req.on("data", function(data) {
                    body += data;
                });

                req.on("end", function() {
                    res.write(body);
                    res.end();
                });

                break;

            case "/hang":
                // Do not respond.
                break;

            case "/getToken":
                var token = req.headers["x-token"];
                res.write(token);
                res.end();
                break;

            case "/404":
                res.writeHead(404, "Not found.");
                res.end();
                break;

            case "/500":
                res.writeHead(500, "Internal server error.");
                res.end();
                break;

            default:
                console.error("Bad path");
                res.writeHead(400, "Bad path");
                res.end();
                break;
        }
    });

    var port = 10492;
    server.listen(port, "127.0.0.1");

    var makeAddr = function(path) {
        return "http://127.0.0.1:" + port + path;
    };

    Tinytest.add("GET /test1 (basic)", function(test) {
        var addr = makeAddr("/test1");
        var res = request.getSync(addr);
        test.equal(res.body, "OK");
    });

    Tinytest.add("GET /test2 (\"more\" async)", function(test) {
        var addr = makeAddr("/test2");
        var res = request.getSync(addr);
        test.equal(res.body, "12345");
    });

    Tinytest.add("GET /test3 (buffer)", function(test) {
        var addr = makeAddr("/test3");
        var res = request.getSync(addr, {
            encoding: null
        });

        test.isTrue(res.body instanceof Buffer, "res.body should be a Buffer");
        for (var i = 0; i < 8; i++) {
            test.equal(res.body[i], i + 1);
        }
    });

    Tinytest.add("POST /test4 (echo binary)", function(test) {
        var addr = makeAddr("/test4");
        var buf = new Buffer([0,1,2]);
        var res = request.postSync(addr, {
            body: buf,
            encoding: null
        });

        test.isTrue(res.body instanceof Buffer, "res.body should be a buffer");
        test.equal(res.body.length, 3);
        test.equal(res.body[0], 0);
        test.equal(res.body[1], 1);
        test.equal(res.body[2], 2);
    });

    Tinytest.add("PATCH /echo", function(test) {
        var addr = makeAddr("/echo");
        var res = request.patchSync(addr, {
            body: "patch test"
        });
        test.equal(res.body, "patch test");
    });

    Tinytest.add("POST /echo", function(test) {
        var addr = makeAddr("/echo");
        var res = request.postSync(addr, {
            body: "post test"
        });
        test.equal(res.body, "post test");
    });

    Tinytest.add("PUT /echo", function(test) {
        var addr = makeAddr("/echo");
        var res = request.putSync(addr, {
            body: "put test"
        });
        test.equal(res.body, "put test");
    });

    Tinytest.add("GET /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.getSync(addr);
        test.equal(res.body, "GET");
    });

    Tinytest.add("PUT /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.putSync(addr);
        test.equal(res.body, "PUT");
    });

    Tinytest.add("PATCH /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.patchSync(addr);
        test.equal(res.body, "PATCH");
    });

    Tinytest.add("POST /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.postSync(addr);
        test.equal(res.body, "POST");
    });

    Tinytest.add("HEAD /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.headSync(addr);
        var method = res.response.headers["x-method"];
        test.equal(method, "HEAD");
    });

    Tinytest.add("DELETE /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.delSync(addr);
        test.equal(res.body, "DELETE");
    });

    Tinytest.add("Just options (url in options)", function(test) {
        try {
            var addr = makeAddr("/method");
            var res = request.getSync({
                url: addr
            });
            test.equal(res.body, "GET");
        } catch (err) {
            test.equal("did not throw", "did throw");
        }
    });

    Tinytest.add("Just options, no options.url should throw", function(test) {
        try {
            var res = request.getSync({ });
            test.equal("did throw", "did not throw");
        } catch (err) {
            test.equal("did throw", "did throw");
        }
    });

    // To me this seems undocumented, but it's how request works.
    Tinytest.add("With parsed url object (surprisingly fails)", function(test) {
        try {
            var addr = makeAddr("/method");
            var uri = url.parse(addr);
            var res = request.getSync(uri);
            test.equal("did throw", "did not throw");
        } catch (err) {
            test.equal("did throw", "did throw");
        }
    });

    Tinytest.add("With parsed url object and options", function(test) {
        try {
            var addr = makeAddr("/getToken");
            var uri = url.parse(addr);
            var res = request.getSync(uri, {
                headers: { "X-TOKEN": "XYZ" }
            });
            test.equal(res.body, "XYZ");
        } catch (err) {
            test.equal("did not throw", "did throw");
        }
    });

    Tinytest.add("With parsed url object in options", function(test) {
        try {
            var addr = makeAddr("/method");
            var uri = url.parse(addr);
            var res = request.getSync({
                uri: uri
            });
            test.equal(res.body, "GET");
        } catch (err) {
            console.error(err);
            test.equal("did not throw", "did throw");
        }
    });

    Tinytest.add("Throw without URI/options", function(test) {
        try {
            request.getSync();
            test.equal("did not throw", "did throw");
        } catch (err) {
            test.equal("did throw", "did throw");
        }
    });

    Tinytest.add("Timeout", function(test) {
        try {
            var addr = makeAddr("/hang");
            request.getSync(addr, {
                timeout: 100
            });
            test.equal("did not throw", "did throw");
        } catch (err) {
            test.equal("did throw", "did throw");
        }
    });

    Tinytest.add("GET /404", function(test) {
        var addr = makeAddr("/404");
        var res = request.getSync(addr);
        test.equal(res.response.statusCode, 404);
    });

    Tinytest.add("GET /500", function(test) {
        var addr = makeAddr("/500");
        var res = request.getSync(addr);
        test.equal(res.response.statusCode, 500);
    });

    Tinytest.add("Test defaults", function(test) {
        try {
            var defaults = request.defaults({
                headers: { "X-TOKEN": "XYZ" }
            });

            var addr = makeAddr("/getToken");
            var res = defaults.getSync(addr);
            test.equal(res.body, "XYZ");
        } catch (err) {
            console.error(err);
            test.equal("did not throw", "did throw");
        }
    });
}

<commit_msg>Add request.sync tests.<commit_after>if (Meteor.isServer) {
    // Start a server to test HTTP client streams.
    var http = Npm.require("http");
    var url = Npm.require("url");
    var server = http.createServer(function(req, res) {
        var url = req.url;

        switch (url) {
            case "/test1":
                res.write("OK");
                res.end();
                break;

            case "/test2":
                res.write("1");
                setTimeout(function() { res.write("2"); }, 10);
                setTimeout(function() { res.write("3"); }, 20);
                setTimeout(function() { res.write("4"); }, 30);
                setTimeout(function() { res.write("5"); }, 40);
                setTimeout(function() { res.end(); }, 50);
                break;

            case "/test3":
                var buf1 = new Buffer([1,2,3,4]);
                res.write(buf1);

                setTimeout(function() {
                    var buf2 = new Buffer([5,6,7,8]);
                    res.write(buf2);

                    res.end();
                }, 50);

                break;

            case "/test4":
                var buffers = [];

                req.on("data", function(data) {
                    buffers.push(data);
                });

                req.on("end", function() {
                    res.write(Buffer.concat(buffers));
                    res.end();
                });

                break;

            case "/method":
                res.setHeader("X-METHOD", "HEAD");

                if (req.method !== "HEAD") {
                    res.write(req.method);
                }

                res.end();
                break;

            case "/echo":
                var body = "";

                req.on("data", function(data) {
                    body += data;
                });

                req.on("end", function() {
                    res.write(body);
                    res.end();
                });

                break;

            case "/hang":
                // Do not respond.
                break;

            case "/getToken":
                var token = req.headers["x-token"];
                res.write(token);
                res.end();
                break;

            case "/404":
                res.writeHead(404, "Not found.");
                res.end();
                break;

            case "/500":
                res.writeHead(500, "Internal server error.");
                res.end();
                break;

            default:
                console.error("Bad path");
                res.writeHead(400, "Bad path");
                res.end();
                break;
        }
    });

    var port = 10492;
    server.listen(port, "127.0.0.1");

    var makeAddr = function(path) {
        return "http://127.0.0.1:" + port + path;
    };

    Tinytest.add("GET /test1 (basic)", function(test) {
        var addr = makeAddr("/test1");
        var res = request.getSync(addr);
        test.equal(res.body, "OK");
    });

    Tinytest.add("GET /test2 (\"more\" async)", function(test) {
        var addr = makeAddr("/test2");
        var res = request.getSync(addr);
        test.equal(res.body, "12345");
    });

    Tinytest.add("GET /test3 (buffer)", function(test) {
        var addr = makeAddr("/test3");
        var res = request.getSync(addr, {
            encoding: null
        });

        test.isTrue(res.body instanceof Buffer, "res.body should be a Buffer");
        for (var i = 0; i < 8; i++) {
            test.equal(res.body[i], i + 1);
        }
    });

    Tinytest.add("POST /test4 (echo binary)", function(test) {
        var addr = makeAddr("/test4");
        var buf = new Buffer([0,1,2]);
        var res = request.postSync(addr, {
            body: buf,
            encoding: null
        });

        test.isTrue(res.body instanceof Buffer, "res.body should be a buffer");
        test.equal(res.body.length, 3);
        test.equal(res.body[0], 0);
        test.equal(res.body[1], 1);
        test.equal(res.body[2], 2);
    });

    Tinytest.add("PATCH /echo", function(test) {
        var addr = makeAddr("/echo");
        var res = request.patchSync(addr, {
            body: "patch test"
        });
        test.equal(res.body, "patch test");
    });

    Tinytest.add("POST /echo", function(test) {
        var addr = makeAddr("/echo");
        var res = request.postSync(addr, {
            body: "post test"
        });
        test.equal(res.body, "post test");
    });

    Tinytest.add("PUT /echo", function(test) {
        var addr = makeAddr("/echo");
        var res = request.putSync(addr, {
            body: "put test"
        });
        test.equal(res.body, "put test");
    });

    Tinytest.add("GET /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.getSync(addr);
        test.equal(res.body, "GET");
    });

    Tinytest.add("PUT /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.putSync(addr);
        test.equal(res.body, "PUT");
    });

    Tinytest.add("PATCH /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.patchSync(addr);
        test.equal(res.body, "PATCH");
    });

    Tinytest.add("POST /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.postSync(addr);
        test.equal(res.body, "POST");
    });

    Tinytest.add("HEAD /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.headSync(addr);
        var method = res.response.headers["x-method"];
        test.equal(method, "HEAD");
    });

    Tinytest.add("DELETE /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.delSync(addr);
        test.equal(res.body, "DELETE");
    });

    Tinytest.add("Just options (url in options)", function(test) {
        try {
            var addr = makeAddr("/method");
            var res = request.getSync({
                url: addr
            });
            test.equal(res.body, "GET");
        } catch (err) {
            test.equal("did not throw", "did throw");
        }
    });

    Tinytest.add("Just options, no options.url should throw", function(test) {
        try {
            var res = request.getSync({ });
            test.equal("did throw", "did not throw");
        } catch (err) {
            test.equal("did throw", "did throw");
        }
    });

    // To me this seems undocumented, but it's how request works.
    Tinytest.add("With parsed url object (surprisingly fails)", function(test) {
        try {
            var addr = makeAddr("/method");
            var uri = url.parse(addr);
            var res = request.getSync(uri);
            test.equal("did throw", "did not throw");
        } catch (err) {
            test.equal("did throw", "did throw");
        }
    });

    Tinytest.add("With parsed url object and options", function(test) {
        try {
            var addr = makeAddr("/getToken");
            var uri = url.parse(addr);
            var res = request.getSync(uri, {
                headers: { "X-TOKEN": "XYZ" }
            });
            test.equal(res.body, "XYZ");
        } catch (err) {
            test.equal("did not throw", "did throw");
        }
    });

    Tinytest.add("With parsed url object in options", function(test) {
        try {
            var addr = makeAddr("/method");
            var uri = url.parse(addr);
            var res = request.getSync({
                uri: uri
            });
            test.equal(res.body, "GET");
        } catch (err) {
            console.error(err);
            test.equal("did not throw", "did throw");
        }
    });

    Tinytest.add("Throw without URI/options", function(test) {
        try {
            request.getSync();
            test.equal("did not throw", "did throw");
        } catch (err) {
            test.equal("did throw", "did throw");
        }
    });

    Tinytest.add("Timeout", function(test) {
        try {
            var addr = makeAddr("/hang");
            request.getSync(addr, {
                timeout: 100
            });
            test.equal("did not throw", "did throw");
        } catch (err) {
            test.equal("did throw", "did throw");
        }
    });

    Tinytest.add("GET /404", function(test) {
        var addr = makeAddr("/404");
        var res = request.getSync(addr);
        test.equal(res.response.statusCode, 404);
    });

    Tinytest.add("GET /500", function(test) {
        var addr = makeAddr("/500");
        var res = request.getSync(addr);
        test.equal(res.response.statusCode, 500);
    });

    Tinytest.add("Test defaults", function(test) {
        try {
            var defaults = request.defaults({
                headers: { "X-TOKEN": "XYZ" }
            });

            var addr = makeAddr("/getToken");
            var res = defaults.getSync(addr);
            test.equal(res.body, "XYZ");
        } catch (err) {
            console.error(err);
            test.equal("did not throw", "did throw");
        }
    });

    Tinytest.add("request.sync should exist", function(test) {
        test.equal(typeof request.sync, "function");
    });

    Tinytest.add("request.sync should default to GET", function(test) {
        var addr = makeAddr("/method");
        var res = request.sync(addr);
        test.equal(res.body, "GET");
    });

    Tinytest.add("request.sync GET should work", function(test) {
        var addr = makeAddr("/method");
        var res = request.sync(addr);
        test.equal(res.body, "GET");
    });

    Tinytest.add("request.sync with options should work", function(test) {
        var addr = makeAddr("/getToken");
        var res = request.sync({
            url: addr,
            headers: { "X-TOKEN": "XYZ" }
        });
        test.equal(res.body, "XYZ");
    });
}

<|endoftext|>


<commit_before>angular.module('driving')
  .controller('UserPageCtrl', function(AuthFactory, $timeout) {
    const userPage = this;

    var myUserId = AuthFactory.getUser();
    // console.log("my user id", myUserId);
    firebase.database().ref('license').orderByChild('uid').equalTo(myUserId).on('value', (snapshot) => {
      console.log("Satuday snapshot val from user page!!!", snapshot.val() );
      var currentUser = snapshot.val()
      //pass current

      for(var key in currentUser) {
        console.log("THIS IS CURRENT USER", currentUser );
        // console.log("Show the currentUser", currentUser[key].userName);
        userPage.userName = currentUser[key].userName;
        userPage.plate = currentUser[key].plate;
        userPage.score = currentUser[key].score;

        firebase.database().ref('messages').orderByChild('plate').equalTo(userPage.plate).on('value', (snapshot) => {
          // console.log("this is user plate snapshot", snapshot.val() );
          var currentUserMessages = snapshot.val();
          // console.log("user message", currentUserMessages);
          userPage.messages = currentUserMessages
            $timeout()
        });
      }
    });
  });
<commit_msg>Update current user config<commit_after>angular.module('driving')
  .controller('UserPageCtrl', function(AuthFactory, $timeout) {
    const userPage = this;

    var myUserId = AuthFactory.getUser();
    console.log("my user id", myUserId);
    firebase.database().ref('license').orderByChild('uid').equalTo(myUserId).on('value', (snapshot) => {
      console.log("Satuday snapshot val from user page!!!", snapshot.val() );
      var currentUser = snapshot.val()
      //pass current

      for(var key in currentUser) {
        console.log("THIS IS CURRENT USER", currentUser );
        // console.log("Show the currentUser", currentUser[key].userName);
        userPage.userName = currentUser[key].userName;
        userPage.plate = currentUser[key].plate;
        userPage.score = currentUser[key].score;

        firebase.database().ref('messages').orderByChild('plate').equalTo(userPage.plate).on('value', (snapshot) => {
          // console.log("this is user plate snapshot", snapshot.val() );
          var currentUserMessages = snapshot.val();
          // console.log("user message", currentUserMessages);
          userPage.messages = currentUserMessages
            $timeout()
        });
      }
    });
  });
<|endoftext|>


<commit_before>function parseSerialData(data, eventEmitter) {

  // data examples:
  // - RF sensor {"DEVICE":[{"G":"0","V":0,"D":11,"DA":"010101011111011101011100"}]}
  // - RF temp {"DEVICE":[{"G":"0201","V":0,"D":31,"DA":15.80000}]}
  // - RF humidity {"DEVICE":[{"G":"0201","V":0,"D":30,"DA":64}]}
  // - Eyes {"DEVICE":[{"G":"0","V":0,"D":999,"DA":"00FF00"}]}
  // - ?? {"DEVICE":[{"G":"0","V":0,"D":1007,"DA":"000000"}]}

  try {
    var message = JSON.parse(data);
    if (!message || !message['DEVICE']) return;

    var deviceDataArray = message['DEVICE'];
    if (!Array.isArray(deviceDataArray)) return;

    deviceDataArray.forEach(function(deviceData) {
      parseDeviceData(deviceData, eventEmitter);
    });

  } catch (err) {
    console.error(err);
    // log err
    return;
  }
}

function parseDeviceData(data, eventEmitter) {
  var deviceId = [data.G,data.V,data.D].join('_');
  var deviceType = getDeviceType(data, deviceId);
  var eventName = deviceId+'.'+deviceType;
  var eventData = {
    event: eventName,
    device: deviceId,
    type: deviceType,
    data: data.DA
  };
  eventEmitter.emit(eventName, eventData);
}

function getDeviceType(data, deviceId) {
  if (deviceId === '0_0_11') {
    return 'rfsensor';
  }
  if (data.G === '0' && data.V === 0) {
    if (data.D === 1007) return '???';
    if (data.D === 999) return 'eyes';
    return 'unknown';
  }
  if (data.G === '0201' && data.V === 0) {
    if (data.D === 30) return 'humidity';
    if (data.D === 31) return 'temperature';
    return 'unknown';
  }
  return 'unknown';
}

exports.parse = parseSerialData;
exports.parseDeviceData = parseDeviceData;<commit_msg>fix known types<commit_after>function parseSerialData(data, eventEmitter) {

  // data examples:
  // - RF sensor {"DEVICE":[{"G":"0","V":0,"D":11,"DA":"010101011111011101011100"}]}
  // - RF temp {"DEVICE":[{"G":"0201","V":0,"D":31,"DA":15.80000}]}
  // - RF humidity {"DEVICE":[{"G":"0201","V":0,"D":30,"DA":64}]}
  // - Eyes {"DEVICE":[{"G":"0","V":0,"D":999,"DA":"00FF00"}]}
  // - ?? {"DEVICE":[{"G":"0","V":0,"D":1007,"DA":"000000"}]}

  try {
    var message = JSON.parse(data);
    if (!message || !message['DEVICE']) return;

    var deviceDataArray = message['DEVICE'];
    if (!Array.isArray(deviceDataArray)) return;

    deviceDataArray.forEach(function(deviceData) {
      parseDeviceData(deviceData, eventEmitter);
    });

  } catch (err) {
    console.error(err);
    // log err
    return;
  }
}

function parseDeviceData(data, eventEmitter) {
  var deviceId = [data.G,data.V,data.D].join('_');
  var deviceType = getDeviceType(data, deviceId);
  var eventName = deviceId+'.'+deviceType;
  var eventData = {
    event: eventName,
    device: deviceId,
    type: deviceType,
    data: data.DA
  };
  eventEmitter.emit(eventName, eventData);
}

function getDeviceType(data, deviceId) {
  if (deviceId === '0_0_11') {
    return 'rfsensor';
  }
  if (data.G === '0' && data.V === 0) {
    if (data.D === 1007) return 'eyes';
    if (data.D === 999) return 'statuslight';
    return 'unknown';
  }
  if (data.G === '0201' && data.V === 0) {
    if (data.D === 30) return 'humidity';
    if (data.D === 31) return 'temperature';
    return 'unknown';
  }
  return 'unknown';
}

exports.parse = parseSerialData;
exports.parseDeviceData = parseDeviceData;<|endoftext|>


<commit_before>var stream = require('stream')
,   util = require('util')
,   Readable = stream.Readable
,   Writable = stream.Writable
,   Transform = stream.Transform

util.inherits(LinkedStreamToObject, Readable)
util.inherits(LinkedStreamToStream, Readable)
util.inherits(StreamToStreamTransform, Transform)

function LinkedStreamToStream(db, reader, stream) {

    if (!(this instanceof LinkedStreamToStream))
        return new LinkedStreamToStream(source);

    Readable.call(this, {objectMode: true})

    this._db = db
    this._reader = reader
    this._stream = stream
}

LinkedStreamToStream.prototype._read = function(size) {

    var self = this

    this._reader.on('end', function() {
        console.log('StreamWrapper closed')
    })

    this._reader.on('error', function (err) {
        console.log(err)
    })

    this._reader.on('data', function (chunk) {
        var start = self._stream + chunk.value['unique']
        var end = start + '\xff'
        console.log('chunk', chunk)
        self._db.createReadStream({start: start, end: end}).on('data', function(data) {
            console.log('to transform')
            self.push([chunk, data])
        })

    })
}

function StreamToStreamTransform() {

    if (!(this instanceof StreamToStreamTransform))
        return new StreamToStreamTransform();

    Transform.call(this, {objectMode: true})

}

StreamToStreamTransform.prototype._transform = function(chunk, encoding, done) {
    console.log('transform recieved', chunk)
    var pusher = chunk[0]
    console.log('pusher', pusher)
    // working on transform NEED ASYNC
    //var parts = chunk.key.split('!')
    //,   streamObj = arrayToObj(parts)
    //console.log('streamObj', streamObj)
    //chunk.value.on('data', function(data) {
    //    var newParts = data.key.split('!')
    //    ,   newStreamObj = arrayToObj(newParts)

    //    console.log('streamObj2', newStreamObj)
    //    for (key in newStreamObj) {
    //        streamObj[key] = newStreamObj[key]
    //    }
    //    console.log('finalobject', streamObj)

    //})
    this.push(pusher)
    done()

}

function arrayToObj(arr) {
    var streamObj = {}
    for (var i=0; i<arr.length-2; i++) {
        streamObj[arr[i]] = arr[i + 2]
    }
    return streamObj
}

function LinkedStreamToObject(db, reader, endpoint) {

    if (!(this instanceof LinkedStreamToObject))
        return new LinkedStreamToObject(reader);

    Readable.call(this, {objectMode: true})

    this._db = db
    this._reader = reader
    this._endpoint = endpoint

}

LinkedStreamToObject.prototype._read = function(size) {

    var self = this

    this._reader.on('end', function() {
        console.log('LinkedStreamToObject closed')
    })

    this._reader.on('error', function (err) {
        console.log(err)
    })

    this._reader.on('data', function (chunk) {
        var key = self._endpoint + '!' + chunk.value['unique'] + '!'
        this._db.get(key, function (err, value) {
            if (err) return console.log('Ooops! Could not get endpoint object', err)
            chunk.value = value
            self.push(chunk)
        })
    })
}

exports.LinkedStreamToObject = LinkedStreamToObject
exports.LinkedStreamToStream = LinkedStreamToStream
exports.StreamToStreamTransform = StreamToStreamTransform<commit_msg>got stream to stream transform working, need to add end object<commit_after>var stream = require('stream')
,   util = require('util')
,   Readable = stream.Readable
,   Writable = stream.Writable
,   Transform = stream.Transform

util.inherits(LinkedStreamToObject, Readable)
util.inherits(LinkedStreamToStream, Readable)
util.inherits(StreamToStreamTransform, Transform)

function LinkedStreamToStream(db, reader, stream) {

    if (!(this instanceof LinkedStreamToStream))
        return new LinkedStreamToStream(source);

    Readable.call(this, {objectMode: true})

    this._db = db
    this._reader = reader
    this._stream = stream
}

LinkedStreamToStream.prototype._read = function(size) {

    var self = this

    this._reader.on('end', function() {
        console.log('StreamWrapper closed')
    })

    this._reader.on('error', function (err) {
        console.log(err)
    })

    this._reader.on('data', function (chunk) {
        var start = self._stream + chunk.value['unique']
        var end = start + '\xff'
        self._db.createReadStream({start: start, end: end}).on('data', function(data) {
            console.log('to transform')
            self.push([chunk, data])
        })

    })
}

function StreamToStreamTransform() {

    if (!(this instanceof StreamToStreamTransform))
        return new StreamToStreamTransform();

    Transform.call(this, {objectMode: true})

}

StreamToStreamTransform.prototype._transform = function(chunk, encoding, done) {
    // need to add destinationObj to output, otherwise seems to be working
    console.log('transform recieved', chunk)
    var startStream = chunk[0].key
    ,   destination = chunk[1]
    ,   endStream = destination.key
    ,   destinationObject = destination.value
    ,   startKeys = startStream.split('!')
    ,   startObj = arrayToObj(startKeys)
    ,   endKeys = endStream.split('!')
    ,   endObj = arrayToObj(endKeys)
    //console.log('streamObj', streamObj)
    for (k in endObj) {
        startObj[k] = endObj[k]
    }
    console.log('finalobject', startObj)
    this.push(startObj)
    done()

}

function arrayToObj(arr) {
    var streamObj = {}
    for (var i=0; i<arr.length-2; i++) {
        streamObj[arr[i]] = arr[i + 2]
    }
    return streamObj
}

function LinkedStreamToObject(db, reader, endpoint) {

    if (!(this instanceof LinkedStreamToObject))
        return new LinkedStreamToObject(reader);

    Readable.call(this, {objectMode: true})

    this._db = db
    this._reader = reader
    this._endpoint = endpoint

}

LinkedStreamToObject.prototype._read = function(size) {

    var self = this

    this._reader.on('end', function() {
        console.log('LinkedStreamToObject closed')
    })

    this._reader.on('error', function (err) {
        console.log(err)
    })

    this._reader.on('data', function (chunk) {
        var key = self._endpoint + '!' + chunk.value['unique'] + '!'
        this._db.get(key, function (err, value) {
            if (err) return console.log('Ooops! Could not get endpoint object', err)
            chunk.value = value
            self.push(chunk)
        })
    })
}

exports.LinkedStreamToObject = LinkedStreamToObject
exports.LinkedStreamToStream = LinkedStreamToStream
exports.StreamToStreamTransform = StreamToStreamTransform<|endoftext|>