<commit_before>'use strict';

describe('Controller: demande', function() {
  let RequestService = {
    getCompletion() {
      return true;
    },

    postAction() {
      return {
        then() {
          return true;
        }
      };
    }
  };

  let toastr = {
    error() {}
  };

  let request = {
    user: 'userId',
    prestations: [],
    status: 'en_cours',
    $update() {}
  };

  let currentUser = {};

  // load the service's module
  beforeEach(module('impactApp'));

  it('should have 16 prestations', function() {
    //given
    var $scope = {};

    //when
    inject(function($controller) {
      $controller('DemandeCtrl', {
        $state: {
          go() {}
        },

        $scope,
        currentUser,
        request,
        RequestService,
        toastr
      });
    });

    expect($scope.prestations.length, 16);
  });

  it('should select the right prestations', function() {
    //given
    var $scope = {};

    //when
    inject(function($controller) {
      $controller('DemandeCtrl', {
        $state: {
          go() {}
        },

        $scope,
        currentUser,
        request,
        RequestService,
        toastr
      });
    });

    $scope.cartestationnement.choice = true;
    $scope.carteinvalidite.choice = true;
    $scope.carteinvalidite.renouvellement = true;
    $scope.submit({$valid: true});

    //then
    expect($scope.request.renouvellements[0]).toEqual('carteinvalidite');
    expect($scope.request.prestations[0]).toEqual('cartestationnement');

  });

});
<commit_msg>refactor demande controller specs<commit_after>'use strict';

describe('Controller: demande', function() {
  let $controller;

  const RequestService = {
    getCompletion() {
      return true;
    },

    postAction() {
      return {
        then() {
          return true;
        }
      };
    }
  };

  const toastr = {
    error() {}
  };

  const $state = {
    go() {}
  };

  let request = {
    user: 'userId',
    prestations: [],
    status: 'en_cours',
    $update() {}
  };

  const currentUser = {};

  // load the service's module
  beforeEach(module('impactApp'));

  beforeEach(inject(function(_$controller_) {
    $controller = _$controller_;
  }));

  describe('prestations list', () => {
    let controller;

    //given
    let $scope = {};

    beforeEach(function() {
      controller = $controller('DemandeCtrl', {
        $state,
        $scope,
        currentUser,
        request,
        RequestService,
        toastr
      });
    });

    it('should have 16 prestations', function() {
      expect(controller.prestations.length, 16);
    });
  });

  describe('prestations request', () => {
    let controller;

    //given
    let $scope = {};

    beforeEach(function() {
      controller = $controller('DemandeCtrl', {
        $state,
        $scope,
        currentUser,
        request,
        RequestService,
        toastr
      });
    });

    it('should select the right prestations', function() {
      //given
      controller.cartestationnement = _.assign(controller.cartestationnement, {choice: true});
      controller.carteinvalidite = _.assign(controller.carteinvalidite, {choice: true, renouvellement: true});

      $scope.submit({$valid: true});

      //then
      expect($scope.request.renouvellements[0]).toEqual('carteinvalidite');
      expect($scope.request.prestations[0]).toEqual('cartestationnement');
    });

  });

});
<|endoftext|>


<commit_before>/*
Name: Mag-importer v0.1.2
Description: similar to html-imports implementation
Author: Michael Glazer
License: MIT
Homepage: https://github.com/magnumjs/mag.js
@requires mag.js & mag addons
(c) 2016
*/
mag.importer = function(url, eleSelector) {

  function checkIfIncluded(file) {
    var links = document.getElementsByTagName("link");
    for (var i = 0; i < links.length; i++) {
      if (links[i].href.substr(-file.length) == file) {
        return true;
      }
    }

    var scripts = document.getElementsByTagName("script");
    for (var i = 0; i < scripts.length; i++) {
      if (scripts[i].src.substr(-file.length) == file) {
        return true;
      }
    }

    return false;
  }

   function getId(id){
    if(mag.importer.ids[id]){
      return id+(++mag.importer.ids[id]);
    } else {
      return id+(mag.importer.ids[id]='');
    }
  }

  function loadInternalScripts(node, type) {
    var scripts = node.getElementsByTagName(type);
    // multiple promises
    var promises = [];
    var names = {}
    for (var i = 0; i < scripts.length; i++) {
      // and doesn't already exist
      var url = type == 'script' ? scripts[i].attributes.src.value : scripts[i].attributes.href.value;
      if (url != "") {

        if (checkIfIncluded(url)) {
          promises.push(mag.importer.namedPromises[url].promise);
          continue;
        }

        var deferred = mag.deferred();
        if (!names[url]) {
          mag.importer.namedPromises[url] = names[url] = deferred;
        } else continue;

        var tag = document.createElement(type);
        tag[(type == 'script' ? 'src' : 'href')] = url;
        if (type == 'link') tag.rel = 'stylesheet';

        tag.onload = function() {
          deferred.resolve(1);
        }

        document.getElementsByTagName("head")[0].appendChild(tag);
        promises.push(deferred.promise);
      }
    }
    return promises;
  }

  return mag.request({
      url: url,
      cache: true
    })
    .then(function(data) {
      //save data
      //get html as node
      var template = document.createElement('template');
      template.innerHTML = data;
      var newNode = template.content.firstChild;

      var promises1 = loadInternalScripts(newNode, 'link');
      var promises2 = loadInternalScripts(newNode, 'script');
      var promises = mag.merge(promises1, promises2);
      var deferred = mag.deferred();

      return mag.when(promises, function() {
        // multiple invocations
        if(eleSelector){
          var node = document.querySelector(eleSelector);
          newNode.children[0].id = eleSelector
          node.appendChild(newNode.children[0]);
          deferred.resolve(eleSelector);
        } else {
          // track incoming ids and increment
           newNode.children[0].id = getId(newNode.children[0].id)
           deferred.resolve({_html: newNode.children[0].outerHTML, id: newNode.children[0].id});
        }
        return deferred.promise;
      });
    });
};
mag.importer.ids = {};
mag.importer.namedPromises = {};
<commit_msg>Update mag-importer.js<commit_after>/*
Name: Mag-importer v0.1.3
Description: similar to html-imports implementation
Author: Michael Glazer
License: MIT
Homepage: https://github.com/magnumjs/mag.js
@requires mag.js & mag addons
(c) 2016
*/

;
(function(mag, document) {

  'use strict';

  mag.importer = function(url, eleSelector) {

    function checkIfIncluded(file, node) {
      var links = node.getElementsByTagName("link");
      for (var i = 0; i < links.length; i++) {
        if (links[i].href.substr(-file.length) == file) {
          return true;
        }
      }

      var scripts = node.getElementsByTagName("script");
      for (var i = 0; i < scripts.length; i++) {
        if (scripts[i].src.substr(-file.length) == file) {
          return true;
        }
      }

      return false;
    }

    function getId(id) {
      if (mag.importer.ids[id]) {
        return id + (++mag.importer.ids[id]);
      } else {
        return id + (mag.importer.ids[id] = '');
      }
    }

    function loadInternalScripts(node, type) {
      var scripts = node.getElementsByTagName(type);
      // multiple promises
      var promises = [];
      var names = {}
      for (var i = 0; i < scripts.length; i++) {
        // and doesn't already exist
        var url = type == 'script' ? scripts[i].attributes.src.value : scripts[i].attributes.href.value;
        if (url != "") {

          if (checkIfIncluded(url, node)) {
            promises.push(mag.importer.namedPromises[url].promise);
            continue;
          }

          var deferred = mag.deferred();
          if (!names[url]) {
            mag.importer.namedPromises[url] = names[url] = deferred;
          } else continue;

          var tag = document.createElement(type);
          tag[(type == 'script' ? 'src' : 'href')] = url;
          if (type == 'link') tag.rel = 'stylesheet';

          tag.onload = function() {
            deferred.resolve(1);
          }

          document.getElementsByTagName("head")[0].appendChild(tag);
          promises.push(deferred.promise);
        }
      }
      return promises;
    }

    return mag.request({
        url: url,
        cache: true
      })
      .then(function(data) {
        //save data
        //get html as node
        var template = document.createElement('template');
        template.innerHTML = data;
        var newNode = template.content.firstChild;

        var promises1 = loadInternalScripts(newNode, 'link');
        var promises2 = loadInternalScripts(newNode, 'script');
        var promises = mag.merge(promises1, promises2);
        var deferred = mag.deferred();

        return mag.when(promises, function() {
          // multiple invocations
          if (eleSelector) {
            var node = document.querySelector(eleSelector);
            newNode.children[0].id = eleSelector
            node.appendChild(newNode.children[0]);
            deferred.resolve(eleSelector);
          } else {
            // track incoming ids and increment
            newNode.children[0].id = getId(newNode.children[0].id)
            deferred.resolve({
              _html: newNode.children[0].outerHTML,
              id: newNode.children[0].id
            });
          }
          return deferred.promise;
        });
      });
  };
  mag.importer.ids = {};
  mag.importer.namedPromises = {};

})(mag, document);
<|endoftext|>


<commit_before>"use strict";

define(['logManager',
    'clientUtil',
    'js/Constants',
    'js/Panels/Grid/GridPanelContainmentControl.DataGridWidgetEventHandlers'], function (logManager,
                                    util,
                                    CONSTANTS,
                                    GridPanelContainmentControlDataGridWidgetEventHandlers) {

    var GridPanelContainmentControl;

    GridPanelContainmentControl = function (options) {
        var self = this;
        this._client = options.client;
        this._panel = options.panel;
        this._dataGridWidget = options.widget;

        this._currentNodeId = null;

        this._selectedObjectChanged = function (__project, nodeId) {
            self.selectedObjectChanged(nodeId);
        };

        this._logger = logManager.create("GridPanelContainmentControl");

        //attach all the event handlers for event's coming from DesignerCanvas
        this.attachDataGridWidgetEventHandlers();

        this._logger.debug("Created");
    };

    GridPanelContainmentControl.prototype.selectedObjectChanged = function (nodeId) {
        var self = this;

        this._logger.debug("SELECTEDOBJECT_CHANGED nodeId '" + nodeId + "'");

        //remove current territory patterns
        if (this._territoryId) {
            this._client.removeUI(this._territoryId);
            this._dataGridWidget.clear();
        }

        this._currentNodeId = nodeId;

        if (this._currentNodeId || this._currentNodeId === CONSTANTS.PROJECT_ROOT_ID) {
            //put new node's info into territory rules
            this._selfPatterns = {};
            this._selfPatterns[nodeId] = { "children": 1 };

            var desc = this._discoverNode(nodeId);
            var title = (desc.Attributes && desc.Attributes.name ? desc.Attributes.name + " " : "N/A ") + "(" + desc.ID + ")";
            this._panel.setTitle(title);

            this._territoryId = this._client.addUI(this, function (events) {
                self._eventCallback(events);
            });
            //update the territory
            this._client.updateTerritory(this._territoryId, this._selfPatterns);
        }
    };

    GridPanelContainmentControl.prototype.destroy = function () {
        this.detachClientEventListeners();
        this._client.removeUI(this._territoryId);
    };

    GridPanelContainmentControl.prototype._eventCallback = function (events) {
        var i = events ? events.length : 0,
            e;

        this._logger.debug("_eventCallback '" + i + "' items");

        this._insertList = [];
        this._updateList = [];
        this._deleteList = [];

        while (i--) {
            e = events[i];
            switch (e.etype) {
                case CONSTANTS.TERRITORY_EVENT_LOAD:
                    this._onLoad(e.eid);
                    break;
                case CONSTANTS.TERRITORY_EVENT_UPDATE:
                    this._onUpdate(e.eid);
                    break;
                case CONSTANTS.TERRITORY_EVENT_UNLOAD:
                    this._onUnload(e.eid);
                    break;
            }
        }

        this._dataGridWidget.insertObjects(this._insertList);
        this._dataGridWidget.updateObjects(this._updateList);
        this._dataGridWidget.deleteObjects(this._deleteList);

        this._logger.debug("_eventCallback '" + events.length + "' items - DONE");
    };

    // PUBLIC METHODS
    GridPanelContainmentControl.prototype._onLoad = function (gmeID) {
        var desc = this._discoverNode(gmeID);

        this._insertList.push(desc);
    };

    GridPanelContainmentControl.prototype._onUpdate = function (gmeID) {
        var desc = this._discoverNode(gmeID);

        this._updateList.push(desc);
    };

    GridPanelContainmentControl.prototype._onUnload = function (gmeID) {
        this._deleteList.push(gmeID);
    };

    GridPanelContainmentControl.prototype._discoverNode = function (gmeID) {
            var nodeDescriptor = {"ID": undefined,
                                  "ParentID": undefined,
                                  "Attributes": undefined,
                                  "Registry": undefined,
                                  "Pointers": undefined},

                cNode = this._client.getNode(gmeID),
                _getNodePropertyValues,
                _getPointerInfo;

            _getNodePropertyValues = function (node, propNameFn, propValueFn) {
                var result =  {},
                    attrNames = node[propNameFn](),
                    len = attrNames.length;

                while (--len >= 0) {
                    result[attrNames[len]] = node[propValueFn](attrNames[len]);
                }

                return result;
            };

            _getPointerInfo = function (node) {
                var result = {},
                    availablePointers = node.getPointerNames(),
                    len = availablePointers.length;

                while (len--) {
                    result[availablePointers[len]] = node.getPointer(availablePointers[len]);
                }

                return result;
            };

            if (cNode) {
                nodeDescriptor.ID = gmeID;
                nodeDescriptor.ParentID = cNode.getParentId();

                nodeDescriptor.Attributes = _getNodePropertyValues(cNode, "getAttributeNames", "getAttribute");
                nodeDescriptor.Registry = _getNodePropertyValues(cNode, "getRegistryNames", "getRegistry");
                nodeDescriptor.Pointers = _getPointerInfo(cNode);
            }

            return nodeDescriptor;
    };

    GridPanelContainmentControl.prototype.attachClientEventListeners = function () {
        this.detachClientEventListeners();
        this._client.addEventListener(this._client.events.SELECTEDOBJECT_CHANGED, this._selectedObjectChanged);
    };

    GridPanelContainmentControl.prototype.detachClientEventListeners = function () {
        this._client.removeEventListener(this._client.events.SELECTEDOBJECT_CHANGED, this._selectedObjectChanged);
    };

    //attach GridPanelContainmentControl - DataGridViewEventHandlers event handler functions
    _.extend(GridPanelContainmentControl.prototype, GridPanelContainmentControlDataGridWidgetEventHandlers.prototype);

    return GridPanelContainmentControl;
});<commit_msg>display guids of the objects<commit_after>"use strict";

define(['logManager',
    'clientUtil',
    'js/Constants',
    'js/Panels/Grid/GridPanelContainmentControl.DataGridWidgetEventHandlers'], function (logManager,
                                    util,
                                    CONSTANTS,
                                    GridPanelContainmentControlDataGridWidgetEventHandlers) {

    var GridPanelContainmentControl;

    GridPanelContainmentControl = function (options) {
        var self = this;
        this._client = options.client;
        this._panel = options.panel;
        this._dataGridWidget = options.widget;

        this._dataGridWidget.setNoWrapColumns(['ID', 'GUID']);

        this._currentNodeId = null;

        this._selectedObjectChanged = function (__project, nodeId) {
            self.selectedObjectChanged(nodeId);
        };

        this._logger = logManager.create("GridPanelContainmentControl");

        //attach all the event handlers for event's coming from DesignerCanvas
        this.attachDataGridWidgetEventHandlers();

        this._logger.debug("Created");
    };

    GridPanelContainmentControl.prototype.selectedObjectChanged = function (nodeId) {
        var self = this;

        this._logger.debug("SELECTEDOBJECT_CHANGED nodeId '" + nodeId + "'");

        //remove current territory patterns
        if (this._territoryId) {
            this._client.removeUI(this._territoryId);
            this._dataGridWidget.clear();
        }

        this._currentNodeId = nodeId;

        if (this._currentNodeId || this._currentNodeId === CONSTANTS.PROJECT_ROOT_ID) {
            //put new node's info into territory rules
            this._selfPatterns = {};
            this._selfPatterns[nodeId] = { "children": 1 };

            var desc = this._discoverNode(nodeId);
            var title = (desc.Attributes && desc.Attributes.name ? desc.Attributes.name + " " : "N/A ") + "(" + desc.ID + ")";
            this._panel.setTitle(title);

            this._territoryId = this._client.addUI(this, function (events) {
                self._eventCallback(events);
            });
            //update the territory
            this._client.updateTerritory(this._territoryId, this._selfPatterns);
        }
    };

    GridPanelContainmentControl.prototype.destroy = function () {
        this.detachClientEventListeners();
        this._client.removeUI(this._territoryId);
    };

    GridPanelContainmentControl.prototype._eventCallback = function (events) {
        var i = events ? events.length : 0,
            e;

        this._logger.debug("_eventCallback '" + i + "' items");

        this._insertList = [];
        this._updateList = [];
        this._deleteList = [];

        while (i--) {
            e = events[i];
            switch (e.etype) {
                case CONSTANTS.TERRITORY_EVENT_LOAD:
                    this._onLoad(e.eid);
                    break;
                case CONSTANTS.TERRITORY_EVENT_UPDATE:
                    this._onUpdate(e.eid);
                    break;
                case CONSTANTS.TERRITORY_EVENT_UNLOAD:
                    this._onUnload(e.eid);
                    break;
            }
        }

        this._dataGridWidget.insertObjects(this._insertList);
        this._dataGridWidget.updateObjects(this._updateList);
        this._dataGridWidget.deleteObjects(this._deleteList);

        this._logger.debug("_eventCallback '" + events.length + "' items - DONE");
    };

    // PUBLIC METHODS
    GridPanelContainmentControl.prototype._onLoad = function (gmeID) {
        var desc = this._discoverNode(gmeID);

        this._insertList.push(desc);
    };

    GridPanelContainmentControl.prototype._onUpdate = function (gmeID) {
        var desc = this._discoverNode(gmeID);

        this._updateList.push(desc);
    };

    GridPanelContainmentControl.prototype._onUnload = function (gmeID) {
        this._deleteList.push(gmeID);
    };

    GridPanelContainmentControl.prototype._discoverNode = function (gmeID) {
            var nodeDescriptor = {"ID": undefined,
                                  "GUID": undefined,
                                  "ParentID": undefined,
                                  "Attributes": undefined,
                                  "Registry": undefined,
                                  "Pointers": undefined},

                cNode = this._client.getNode(gmeID),
                _getNodePropertyValues,
                _getPointerInfo;

            _getNodePropertyValues = function (node, propNameFn, propValueFn) {
                var result =  {},
                    attrNames = node[propNameFn](),
                    len = attrNames.length;

                while (--len >= 0) {
                    result[attrNames[len]] = node[propValueFn](attrNames[len]);
                }

                return result;
            };

            _getPointerInfo = function (node) {
                var result = {},
                    availablePointers = node.getPointerNames(),
                    len = availablePointers.length;

                while (len--) {
                    result[availablePointers[len]] = node.getPointer(availablePointers[len]);
                }

                return result;
            };

            if (cNode) {
                nodeDescriptor.ID = gmeID;
                nodeDescriptor.GUID = cNode.getGuid();
                nodeDescriptor.ParentID = cNode.getParentId();

                nodeDescriptor.Attributes = _getNodePropertyValues(cNode, "getAttributeNames", "getAttribute");
                nodeDescriptor.Registry = _getNodePropertyValues(cNode, "getRegistryNames", "getRegistry");
                nodeDescriptor.Pointers = _getPointerInfo(cNode);
            }

            return nodeDescriptor;
    };

    GridPanelContainmentControl.prototype.attachClientEventListeners = function () {
        this.detachClientEventListeners();
        this._client.addEventListener(this._client.events.SELECTEDOBJECT_CHANGED, this._selectedObjectChanged);
    };

    GridPanelContainmentControl.prototype.detachClientEventListeners = function () {
        this._client.removeEventListener(this._client.events.SELECTEDOBJECT_CHANGED, this._selectedObjectChanged);
    };

    //attach GridPanelContainmentControl - DataGridViewEventHandlers event handler functions
    _.extend(GridPanelContainmentControl.prototype, GridPanelContainmentControlDataGridWidgetEventHandlers.prototype);

    return GridPanelContainmentControl;
});<|endoftext|>


<commit_before>import CX from "classnames";
import React from "react";
import { Col, Row } from "react-bootstrap";
import { connect } from "react-redux";
import { Flex, FlexItem } from "../../../base/index";
import { toScientificNotation } from "../../../utils";
import { toggleExpanded } from "../../actions";

import AnalysisValueLabel from "../ValueLabel";

export const PathoscopeItem = (props) => {

    const className = CX("list-group-item", "spaced", {hoverable: !props.expanded});

    let closeButton;

    if (props.expanded) {
        closeButton = (
            <button type="button" className="close" onClick={() => props.onExpand(props.id)}>
                ×
            </button>
        );
    }

    const piValue = props.showReads ? Math.round(props.reads) : toScientificNotation(props.pi);

    return (

 props.onExpand(props.id)}>
            <Row>
                <Col xs={12} md={6}>
                    <Flex>
                        <FlexItem>
                            {props.name}
                        </FlexItem>
                        <FlexItem pad={5}>

                                    {props.abbreviation}

                        </FlexItem>
                    </Flex>
                </Col>

                <Col xs={12} mdHidden lgHidden>

                </Col>

                <Col xs={6} sm={4} md={2}>
                    <AnalysisValueLabel
                        bsStyle="success"
                        label={props.showReads ? "Reads" : "Weight"}
                        value={piValue}
                    />
                </Col>
                <Col xs={6} sm={4} md={2}>
                    <AnalysisValueLabel
                        bsStyle="danger"
                        label="Depth"
                        value={props.depth.toFixed(1)}
                    />
                </Col>
                <Col xs={6} sm={4} md={2}>
                    <Flex justifyContent="space-between">
                        <FlexItem>
                            <AnalysisValueLabel
                                bsStyle="primary"
                                label="Coverage"
                                value={props.coverage.toFixed(3)}
                            />
                        </FlexItem>
                        <FlexItem>
                            {closeButton}
                        </FlexItem>
                    </Flex>
                </Col>
            </Row>

    );
};

const mapStateToProps = (state, ownProps) => ({
    ...state.analyses.data[ownProps.index],
    showMedian: state.analyses.showMedian,
    showReads: state.analyses.showReads
});

const mapDispatchToProps = (dispatch) => ({

    onExpand: (id) => {
        dispatch(toggleExpanded(id));
    }
});

export default connect(mapStateToProps, mapDispatchToProps)(PathoscopeItem);
<commit_msg>Update Pathoscope entry UI<commit_after>import CX from "classnames";
import React from "react";
import { Col, Row } from "react-bootstrap";
import { connect } from "react-redux";
import { Flex, FlexItem } from "../../../base/index";
import { toScientificNotation } from "../../../utils";
import { toggleExpanded } from "../../actions";
import AnalysisValueLabel from "../ValueLabel";

export const PathoscopeItem = (props) => {

    const className = CX("list-group-item", "spaced", {hoverable: !props.expanded});

    let closeButton;

    if (props.expanded) {
        closeButton = (
            <button type="button" className="close pull-right" onClick={() => props.onExpand(props.id)}>
                ×
            </button>
        );
    }

    const piValue = props.showReads ? Math.round(props.reads) : toScientificNotation(props.pi);

    return (

 props.onExpand(props.id)}>
            <Row>
                <Col xs={12} sm={5} md={5}>
                    <Flex>
                        <FlexItem>
                            {props.name}
                        </FlexItem>
                        <FlexItem pad={5}>

                                    {props.abbreviation}

                        </FlexItem>
                    </Flex>
                </Col>
                <Col xs={4} sm={2} md={2}>
                    <AnalysisValueLabel
                        bsStyle="success"
                        label={props.showReads ? "Reads" : "Weight"}
                        value={piValue}
                    />
                </Col>
                <Col xs={3} sm={2} md={2}>
                    <AnalysisValueLabel
                        bsStyle="danger"
                        label="Depth"
                        value={props.depth.toFixed(1)}
                    />
                </Col>
                <Col xs={3} sm={2} md={2}>
                    <AnalysisValueLabel
                        bsStyle="primary"
                        label="Coverage"
                        value={props.coverage.toFixed(3)}
                    />
                </Col>
                <Col xs={2} sm={1} md={1}>
                    {closeButton}
                </Col>
            </Row>

    );
};

const mapStateToProps = (state, ownProps) => ({
    ...state.analyses.data[ownProps.index],
    showMedian: state.analyses.showMedian,
    showReads: state.analyses.showReads
});

const mapDispatchToProps = (dispatch) => ({

    onExpand: (id) => {
        dispatch(toggleExpanded(id));
    }
});

export default connect(mapStateToProps, mapDispatchToProps)(PathoscopeItem);
<|endoftext|>


<commit_before>(function(undefined) {
  var isString = function(obj) {
    return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
  };

  var isObject = function(obj) {
    return obj === Object(obj);
  };

  var isFunction = $.isFunction;

  var getJSON = function(url, callback) {
    var options = {
      url: url,
      dataType: 'json',
      success: callback
    };

    if (SC.Resource.errorHandler) {
      options.error = SC.Resource.errorHandler;
    }

    return $.ajax(options);
  };

  SC.Resource = SC.Object.extend({
    isSCResource: true,

    fetch: function() {
      this.set('resourceState', SC.Resource.Lifecycle.FETCHING);

      var self = this;

      this.deferedFetch = getJSON(this.resourceURL(), function(json) {
        self.set('data', self.constructor.parse(json));
      });

      this.deferedFetch.always(function() {
        self.set('resourceState', SC.Resource.Lifecycle.FETCHED);
      });

      return this.deferedFetch;
    },

    resourceURL: function() {
      return this.constructor.resourceURL(this);
    },

    // Turn this resource into a JSON object to be saved via AJAX. Override
    // this method to produce different syncing behavior.
    toJSON: function() {
      return this.get('data');
    },

    isNew: function() {
      return !this.get('id');
    },

    save: function() {
      var ajaxOptions = {
        data: this.toJSON()
      };

      if (this.isNew()) {
        ajaxOptions.type = 'POST';
        ajaxOptions.url = this.constructor.resourceURL();
      } else {
        ajaxOptions.type = 'PUT';
        ajaxOptions.url = this.resourceURL();
      }

      return $.ajax(ajaxOptions);
    }
  });

  SC.Resource.Lifecycle = {
    INITIALIZING: 0,
    UNFETCHED:    10,
    FETCHING:     20,
    FETCHED:      30,
    create: function(options) {
      options = options || {};
      options.resourceState = SC.Resource.Lifecycle.INITIALIZING;
      var instance = this._super.call(this, options);
      if (instance.get('resourceState') === SC.Resource.Lifecycle.INITIALIZING) {
        instance.set('resourceState', SC.Resource.Lifecycle.UNFETCHED);
      }
      return instance;
    }
  };

  SC.Resource.reopenClass(SC.Resource.Lifecycle);

  var expandSchemaItem = function(schema, name) {
    var value = schema[name];

    if (value === Number || value === String || value === Boolean || value === Date || value === Object) {
      value = {type: value};
    }

    if (isObject(value) && value.type) {

      if (value.type.isSCResource || isString(value.type)) {
        value.nested = !!value.nested;

        if (value.nested) {
          value.key = value.key || name;

          value.serialize = value.serialize || function(instance) {
            return instance.get('data');
          };
          value.deserialize = value.deserialize || function(data) {
            if (isString(value.type)) {
              value.type = SC.getPath(value.type);
            }
            return value.type.create(data);
          };
        } else {
          value.key = value.key || name + '_id';
          if (!schema[value.key]) {
            schema[value.key] = Number;
            expandSchemaItem(schema, value.key);
          }

          value.serialize = value.serialize || function(instance) {
            return instance.get('id');
          };
          value.deserialize = value.deserialize || function(id) {
            if (isString(value.type)) {
              value.type = SC.getPath(value.type);
            }
            return value.type.create({id: id});
          };
        }

      } else if(value.type.isSCResourceCollection) {
        if (value.url) {
          value.deserialize = value.deserialize || function(options) {
            if (isString(value.itemType)) {
              value.itemType = SC.getPath(value.itemType);
            }
            options.type = value.itemType;

            return value.type.create(options);
          };
        } else if (value.nested) {
          value.key = value.key || name;
          value.deserialize = value.deserialize || function(data) {
            if (isString(value.itemType)) {
              value.itemType = SC.getPath(value.itemType);
            }
            return value.type.create({
              content: data,
              type: value.itemType,
              parse: value.parse
            });
          };
        }
      } else {
        value.key = value.key || name;
      }

      var serializer;
      switch (value.type) {
        case Number:
          serializer = function(v) { return v === undefined ? undefined : ( v === null ? null : Number(v) ); };
          break;
        case String:
          serializer = function(v) { return v === undefined ? undefined : ( v === null ? null : '' + v ); };
          break;
        case Boolean:
          serializer = function(v) { return v === true || v === 'true'; };
          break;
        case Date:
          serializer = function(v) { return v === undefined ? undefined : ( v === null ? null : new Date(v) ); };
          break;
        case Object:
          serializer = function(v) { return v; };
          break;
      }

      if (serializer) {
        value.serialize   = value.serialize   || serializer;
        value.deserialize = value.deserialize || serializer;
      }
    }
    schema[name] = value;
  };

  var expandSchema = function(schema) {
    for (var name in schema) {
      if (schema.hasOwnProperty(name)) {
        expandSchemaItem(schema, name);
      }
    }

    return schema;
  };

  var createSchemaProperties = function(schema) {
    var properties = {};

    for (var propertyName in schema) {
      if (schema.hasOwnProperty(propertyName)) {
        if (schema[propertyName].key) {
          properties[propertyName] = function(name, value) {
            var propertyOptions = schema[name];
            var data = this.get('data');

            if (arguments.length === 1) { // getter
              if (!data || !data.hasOwnProperty(propertyOptions.key)) {
                this.fetch();
                return;
              } else {
                value = propertyOptions.deserialize(SC.getPath(data, propertyOptions.key));
              }
            } else { // setter
              SC.setPath(data, propertyOptions.key, propertyOptions.serialize(value));
            }

            return value;
          }.property('data').cacheable();
        } else if (schema[propertyName].url) {
          properties[propertyName] = function(name, value) {
            var propertyOptions = schema[name];

            if (value === void(0)) {
              var options = SC.copy(propertyOptions);

              if ($.isFunction(options.url)) {
                options.url = options.url(this);
              } else if ('string' === typeof options.url) {
                options.url = options.url.fmt(this.get('id'));
              }

              return propertyOptions.deserialize(options);
            } else {
              // throw "You can not set this property";
            }
          }.property('id').cacheable();
        }
      }
    }

    return properties;
  };

  SC.Resource.reopenClass({
    isSCResource: true,

    // Create an instance of this resource. If `options` includes an
    // `id`, first check the identity map and return the existing resource
    // with that ID if found.
    create: function(options) {
      var instance;
      if (options && options.id) {
        var id = options.id.toString();
        this.identityMap = this.identityMap || {};
        instance = this.identityMap[id];
        if (!instance) {
          this.identityMap[id] = instance = this._super.call(this);
          instance.set('data', options);
        }
      } else {
        instance = this._super.call(this);
        instance.set('data', options);
      }
      return instance;
    },

    // Parse JSON -- likely returned from an AJAX call -- into the
    // properties for an instance of this resource. Override this method
    // to produce different parsing behavior.
    parse: function(json) {
      return json;
    },

    // Define a resource class.
    //
    // Parameters:
    //
    //  * `schema` -- the properties schema for the resource class
    //  * `url` -- either a function that returns the URL for syncing
    //    resources or a string. If the latter, a string of the form
    //    "/widgets" is turned into a function that returns "/widgets" if
    //    the Widget's ID is not present and "/widgets/{id}" if it is.
    //  * `parse` -- the function used to parse JSON returned from AJAX
    //    calls into the resource properties. By default, simply returns
    //    the JSON.
    define: function(options) {
      options = options || {};
      var schema = expandSchema(options.schema);

      var klass = this.extend(createSchemaProperties(schema));

      var classOptions = {
        url: options.url,
        schema: schema
      };

      if (options.parse) {
        classOptions.parse = options.parse;
      }

      klass.reopenClass(classOptions);

      return klass;
    },

    resourceURL: function(instance) {
      if ($.isFunction(this.url)) {
        return this.url(instance);
      } else {
        if (instance) {
          return this.url + '/' + instance.get('id');
        } else {
          return this.url;
        }
      }
    }
  });

  SC.ResourceCollection = SC.ArrayProxy.extend({
    isSCResourceCollection: true,
    type: SC.Required,
    fetch: function() {
      if (!this.prePopulated && this.get('resourceState') === SC.Resource.Lifecycle.UNFETCHED) {
        this.set('resourceState', SC.Resource.Lifecycle.FETCHING);
        var self = this;

        this.deferedFetch = this._fetch(function(json) {
          self.set('content', self.instantiateItems(self.parse(json)));
        });

        this.deferedFetch.always(function() {
          self.set('resourceState', SC.Resource.Lifecycle.FETCHED);
        });
      }
      return this.deferedFetch;
    },
    _fetch: function(callback) {
      return getJSON(this.url || this.type.resourceURL(), callback);
    },
    instantiateItems: function(items) {
      return items.map(function(item) {
        if (item instanceof this.type) {
          return item;
        } else {
          return this.type.create(item);
        }
      }, this);
    },
    parse: function(json) {
      return _.map(json, this.type.parse);
    },
    content: function(name, value) {
      if (value === void(0)) {
        this.fetch();
        return this.realContent;
      } else {
        this.realContent = this.instantiateItems(value);
        return value;
      }
    }.property()
  });

  SC.ResourceCollection.reopenClass(SC.Resource.Lifecycle);

  SC.ResourceCollection.reopenClass({
    isSCResourceCollection: true,
    create: function(options) {
      options = options || {};
      var content = options.content;
      delete options.content;

      options.prePopulated = !! content;

      var instance = this._super.call(this, options);

      if (content) {
        instance.set('content', content);
      }

      return instance;
    }
  });
}());
<commit_msg>Extracted createPropertyFunction and createHasManyFunction from createSchemaProperties<commit_after>(function(undefined) {
  var isString = function(obj) {
    return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
  };

  var isObject = function(obj) {
    return obj === Object(obj);
  };

  var isFunction = $.isFunction;

  var getJSON = function(url, callback) {
    var options = {
      url: url,
      dataType: 'json',
      success: callback
    };

    if (SC.Resource.errorHandler) {
      options.error = SC.Resource.errorHandler;
    }

    return $.ajax(options);
  };

  SC.Resource = SC.Object.extend({
    isSCResource: true,

    fetch: function() {
      this.set('resourceState', SC.Resource.Lifecycle.FETCHING);

      var self = this;

      this.deferedFetch = getJSON(this.resourceURL(), function(json) {
        self.set('data', self.constructor.parse(json));
      });

      this.deferedFetch.always(function() {
        self.set('resourceState', SC.Resource.Lifecycle.FETCHED);
      });

      return this.deferedFetch;
    },

    resourceURL: function() {
      return this.constructor.resourceURL(this);
    },

    // Turn this resource into a JSON object to be saved via AJAX. Override
    // this method to produce different syncing behavior.
    toJSON: function() {
      return this.get('data');
    },

    isNew: function() {
      return !this.get('id');
    },

    save: function() {
      var ajaxOptions = {
        data: this.toJSON()
      };

      if (this.isNew()) {
        ajaxOptions.type = 'POST';
        ajaxOptions.url = this.constructor.resourceURL();
      } else {
        ajaxOptions.type = 'PUT';
        ajaxOptions.url = this.resourceURL();
      }

      return $.ajax(ajaxOptions);
    }
  });

  SC.Resource.Lifecycle = {
    INITIALIZING: 0,
    UNFETCHED:    10,
    FETCHING:     20,
    FETCHED:      30,
    create: function(options) {
      options = options || {};
      options.resourceState = SC.Resource.Lifecycle.INITIALIZING;
      var instance = this._super.call(this, options);
      if (instance.get('resourceState') === SC.Resource.Lifecycle.INITIALIZING) {
        instance.set('resourceState', SC.Resource.Lifecycle.UNFETCHED);
      }
      return instance;
    }
  };

  SC.Resource.reopenClass(SC.Resource.Lifecycle);

  var expandSchemaItem = function(schema, name) {
    var value = schema[name];

    if (value === Number || value === String || value === Boolean || value === Date || value === Object) {
      value = {type: value};
    }

    if (isObject(value) && value.type) {

      if (value.type.isSCResource || isString(value.type)) {
        value.nested = !!value.nested;

        if (value.nested) {
          value.key = value.key || name;

          value.serialize = value.serialize || function(instance) {
            return instance.get('data');
          };
          value.deserialize = value.deserialize || function(data) {
            if (isString(value.type)) {
              value.type = SC.getPath(value.type);
            }
            return value.type.create(data);
          };
        } else {
          value.key = value.key || name + '_id';
          if (!schema[value.key]) {
            schema[value.key] = Number;
            expandSchemaItem(schema, value.key);
          }

          value.serialize = value.serialize || function(instance) {
            return instance.get('id');
          };
          value.deserialize = value.deserialize || function(id) {
            if (isString(value.type)) {
              value.type = SC.getPath(value.type);
            }
            return value.type.create({id: id});
          };
        }

      } else if(value.type.isSCResourceCollection) {
        if (value.url) {
          value.deserialize = value.deserialize || function(options) {
            if (isString(value.itemType)) {
              value.itemType = SC.getPath(value.itemType);
            }
            options.type = value.itemType;

            return value.type.create(options);
          };
        } else if (value.nested) {
          value.key = value.key || name;
          value.deserialize = value.deserialize || function(data) {
            if (isString(value.itemType)) {
              value.itemType = SC.getPath(value.itemType);
            }
            return value.type.create({
              content: data,
              type: value.itemType,
              parse: value.parse
            });
          };
        }
      } else {
        value.key = value.key || name;
      }

      var serializer;
      switch (value.type) {
        case Number:
          serializer = function(v) { return v === undefined ? undefined : ( v === null ? null : Number(v) ); };
          break;
        case String:
          serializer = function(v) { return v === undefined ? undefined : ( v === null ? null : '' + v ); };
          break;
        case Boolean:
          serializer = function(v) { return v === true || v === 'true'; };
          break;
        case Date:
          serializer = function(v) { return v === undefined ? undefined : ( v === null ? null : new Date(v) ); };
          break;
        case Object:
          serializer = function(v) { return v; };
          break;
      }

      if (serializer) {
        value.serialize   = value.serialize   || serializer;
        value.deserialize = value.deserialize || serializer;
      }
    }
    schema[name] = value;
  };

  var expandSchema = function(schema) {
    for (var name in schema) {
      if (schema.hasOwnProperty(name)) {
        expandSchemaItem(schema, name);
      }
    }

    return schema;
  };

  // Build and return the function for a given regular property.
  function createPropertyFunction(propertyOptions) {
    return function(name, value) {
      var data = this.get('data');

      if (arguments.length === 1) { // getter
        if (!data || !data.hasOwnProperty(propertyOptions.key)) {
          this.fetch();
          return;
        } else {
          value = propertyOptions.deserialize(SC.getPath(data, propertyOptions.key));
        }
      } else { // setter
        SC.setPath(data, propertyOptions.key, propertyOptions.serialize(value));
      }

      return value;
    }.property('data').cacheable();
  }

  // Build and return the function for a given HasMany property.
  function createHasManyFunction(propertyOptions) {
    return function(name, value) {
      if (value === void(0)) {
        var options = SC.copy(propertyOptions);

        if ($.isFunction(options.url)) {
          options.url = options.url(this);
        } else if ('string' === typeof options.url) {
          options.url = options.url.fmt(this.get('id'));
        }

        return propertyOptions.deserialize(options);
      } else {
        // throw "You can not set this property";
      }
    }.property('id').cacheable();
  }

  function createSchemaProperties(schema) {
    var properties = {}, propertyOptions;

    for (var propertyName in schema) {
      if (schema.hasOwnProperty(propertyName)) {
        propertyOptions = schema[propertyName];
        properties[propertyName] = propertyOptions.key ? createPropertyFunction(propertyOptions)
                                                       : createHasManyFunction(propertyOptions);
      }
    }

    return properties;
  };

  SC.Resource.reopenClass({
    isSCResource: true,

    // Create an instance of this resource. If `options` includes an
    // `id`, first check the identity map and return the existing resource
    // with that ID if found.
    create: function(options) {
      var instance;
      if (options && options.id) {
        var id = options.id.toString();
        this.identityMap = this.identityMap || {};
        instance = this.identityMap[id];
        if (!instance) {
          this.identityMap[id] = instance = this._super.call(this);
          instance.set('data', options);
        }
      } else {
        instance = this._super.call(this);
        instance.set('data', options);
      }
      return instance;
    },

    // Parse JSON -- likely returned from an AJAX call -- into the
    // properties for an instance of this resource. Override this method
    // to produce different parsing behavior.
    parse: function(json) {
      return json;
    },

    // Define a resource class.
    //
    // Parameters:
    //
    //  * `schema` -- the properties schema for the resource class
    //  * `url` -- either a function that returns the URL for syncing
    //    resources or a string. If the latter, a string of the form
    //    "/widgets" is turned into a function that returns "/widgets" if
    //    the Widget's ID is not present and "/widgets/{id}" if it is.
    //  * `parse` -- the function used to parse JSON returned from AJAX
    //    calls into the resource properties. By default, simply returns
    //    the JSON.
    define: function(options) {
      options = options || {};
      var schema = expandSchema(options.schema);

      var klass = this.extend(createSchemaProperties(schema));

      var classOptions = {
        url: options.url,
        schema: schema
      };

      if (options.parse) {
        classOptions.parse = options.parse;
      }

      klass.reopenClass(classOptions);

      return klass;
    },

    resourceURL: function(instance) {
      if ($.isFunction(this.url)) {
        return this.url(instance);
      } else {
        if (instance) {
          return this.url + '/' + instance.get('id');
        } else {
          return this.url;
        }
      }
    }
  });

  SC.ResourceCollection = SC.ArrayProxy.extend({
    isSCResourceCollection: true,
    type: SC.Required,
    fetch: function() {
      if (!this.prePopulated && this.get('resourceState') === SC.Resource.Lifecycle.UNFETCHED) {
        this.set('resourceState', SC.Resource.Lifecycle.FETCHING);
        var self = this;

        this.deferedFetch = this._fetch(function(json) {
          self.set('content', self.instantiateItems(self.parse(json)));
        });

        this.deferedFetch.always(function() {
          self.set('resourceState', SC.Resource.Lifecycle.FETCHED);
        });
      }
      return this.deferedFetch;
    },
    _fetch: function(callback) {
      return getJSON(this.url || this.type.resourceURL(), callback);
    },
    instantiateItems: function(items) {
      return items.map(function(item) {
        if (item instanceof this.type) {
          return item;
        } else {
          return this.type.create(item);
        }
      }, this);
    },
    parse: function(json) {
      return _.map(json, this.type.parse);
    },
    content: function(name, value) {
      if (value === void(0)) {
        this.fetch();
        return this.realContent;
      } else {
        this.realContent = this.instantiateItems(value);
        return value;
      }
    }.property()
  });

  SC.ResourceCollection.reopenClass(SC.Resource.Lifecycle);

  SC.ResourceCollection.reopenClass({
    isSCResourceCollection: true,
    create: function(options) {
      options = options || {};
      var content = options.content;
      delete options.content;

      options.prePopulated = !! content;

      var instance = this._super.call(this, options);

      if (content) {
        instance.set('content', content);
      }

      return instance;
    }
  });
}());
<|endoftext|>


<commit_before>module.exports = {
  assemble: function (value, expiration) {
    if (typeof value === 'function') {
      throw new TypeError('Only serializables values can be cached');
    }

    return JSON.stringify({ value: value, expiration: expiration });
  },
  key: function (namespace, key) {
    if (!namespace) {
      namespace = key;
      key = [];
    }
    if (key instanceof Array) {
      key = [namespace].concat(key);
    } else {
      key = (namespace + '/' + key).split('/');
    }

    return key.filter(String).join('/').replace(/\s/g,'');
  }
};
<commit_msg>accept key on assemble<commit_after>module.exports = {
  assemble: function (value, expiration, key) {
    if (typeof value === 'function') {
      throw new TypeError('Only serializables values can be cached');
    }

    var obj = { value: value, expiration: expiration };

    if (key) {
      obj.key = key;
    }

    return JSON.stringify(obj);
  },
  key: function (namespace, key) {
    if (!namespace) {
      namespace = key;
      key = [];
    }
    if (key instanceof Array) {
      key = [namespace].concat(key);
    } else {
      key = (namespace + '/' + key).split('/');
    }

    return key.filter(String).join('/').replace(/\s/g,'');
  }
};
<|endoftext|>


<commit_before>import Orbit from 'orbit/core';
import clone from 'orbit/lib/clone';
import diffs from 'orbit/lib/diffs';
import eq from 'orbit/lib/eq';

var TransformConnector = function(source, target, options) {
  var _this = this;

  this.source = source;
  this.target = target;

  options = options || {};
// TODO - allow filtering of transforms
//  if (options.actions) this.actions = Orbit.arrayToOptions(options.actions);
//  if (options.types) this.types = Orbit.arrayToOptions(options.types);
  this.blocking = options.blocking !== undefined ? options.blocking : true;
  var active = options.active !== undefined ? options.active : true;

  if (active) this.activate();
};

TransformConnector.prototype = {
  constructor: TransformConnector,

  activate: function() {
    var _this = this;

    if (this._active) return;

    this.source.on('didTransform',  this._processTransform,  this);

    this._active = true;
  },

  deactivate: function() {
    this.source.off('didTransform',  this._processTransform,  this);

    this._active = false;
  },

  isActive: function() {
    return this._active;
  },

  /////////////////////////////////////////////////////////////////////////////
  // Internals
  /////////////////////////////////////////////////////////////////////////////

  _processTransform: function(operation) {
// TODO - add filtering back in
//    if (this.actions && !this.actions[action]) return;
//    if (this.types && !this.types[type]) return;

//    console.log(this.target.id, 'processTransform', operation);
    if (this.blocking) {
      return this._transformTarget(operation);

    } else {
      this._transformTarget(operation);
    }
  },

  _transformTarget: function(operation) {
//TODO-log    console.log('****', ' transform from ', this.source.id, ' to ', this.target.id, operation);

    if (this.target.retrieve) {
      var currentValue = this.target.retrieve(operation.path);

      if (currentValue) {
        if (operation.op === 'add' || operation.op === 'replace') {
          if (eq(currentValue, operation.value)) {
//TODO-log            console.log('==', ' transform from ', this.source.id, ' to ', this.target.id, operation);
            return;
          } else {
            return this._resolveConflicts(operation.path, currentValue, operation.value);
          }
        }
      } else if (operation.op === 'remove') {
        return;
      }
    }

    return this.target.transform(operation);
  },

  _resolveConflicts: function(path, currentValue, updatedValue) {
    var ops = diffs(currentValue, updatedValue, {basePath: path});

//TODO-log    console.log(this.target.id, 'resolveConflicts', path, currentValue, updatedValue, ops);

    return this.target.transform(ops);
  }
};

export default TransformConnector;<commit_msg>Add a transform queue on the connector<commit_after>import Orbit from 'orbit/core';
import TransformQueue from 'orbit/transform_queue';
import clone from 'orbit/lib/clone';
import diffs from 'orbit/lib/diffs';
import eq from 'orbit/lib/eq';

var TransformConnector = function(source, target, options) {
  this.source = source;
  this.target = target;
  this.transformQueue = new TransformQueue(this, {autoProcess: false});

  options = options || {};
// TODO - allow filtering of transforms
//  if (options.actions) this.actions = Orbit.arrayToOptions(options.actions);
//  if (options.types) this.types = Orbit.arrayToOptions(options.types);
  this.blocking = options.blocking !== undefined ? options.blocking : true;
  var active = options.active !== undefined ? options.active : true;

  if (active) this.activate();
};

TransformConnector.prototype = {
  constructor: TransformConnector,

  activate: function() {
    var _this = this;

    if (this._active) return;

    this.source.on('didTransform',  this._processTransform,  this);
    this.target.transformQueue.on('didComplete', this.transformQueue.process, this.transformQueue);

    this._active = true;
  },

  deactivate: function() {
    this.source.off('didTransform',  this._processTransform,  this);
    this.target.transformQueue.off('didComplete', this.transformQueue.process, this.transformQueue);

    this._active = false;
  },

  isActive: function() {
    return this._active;
  },

  /////////////////////////////////////////////////////////////////////////////
  // Internals
  /////////////////////////////////////////////////////////////////////////////

  _processTransform: function(operation) {
// TODO - add filtering back in
//    if (this.actions && !this.actions[action]) return;
//    if (this.types && !this.types[type]) return;

//    console.log(this.target.id, 'processTransform', operation);
    if (this.blocking) {
      return this._transform(operation);

    } else {
      this._transform(operation);
    }
  },

  _transform: function(operation) {
    // If the target's transformQueue is processing, then we should queue up the
    // transform on the connector instead of on the target.
    // This ensures that comparisons are made against the target's most up to
    // date state. Note that this connector's queue processing is triggered
    // by the `didComplete` event for the target's queue.
    if (this.target.transformQueue.processing) {
      return this.transformQueue.push(operation);
    }

//TODO-log    console.log('****', ' transform from ', this.source.id, ' to ', this.target.id, operation);

    if (this.target.retrieve) {
      var currentValue = this.target.retrieve(operation.path);

      if (currentValue) {
        if (operation.op === 'add' || operation.op === 'replace') {
          if (eq(currentValue, operation.value)) {
//TODO-log            console.log('==', ' transform from ', this.source.id, ' to ', this.target.id, operation);
            return;
          } else {
            return this._resolveConflicts(operation.path, currentValue, operation.value);
          }
        }
      } else if (operation.op === 'remove') {
        return;
      }
    }

    return this.target.transform(operation);
  },

  _resolveConflicts: function(path, currentValue, updatedValue) {
    var ops = diffs(currentValue, updatedValue, {basePath: path});

//TODO-log    console.log(this.target.id, 'resolveConflicts', path, currentValue, updatedValue, ops);

    return this.target.transform(ops);
  }
};

export default TransformConnector;<|endoftext|>


<commit_before>import { WidthSpriteSheetHero, HeightSpriteSheetHero, Width, Height } from '../Constants.js';
import { Tileset, Level1, HeroSprite } from '../ConstantsKey.js';
import Character from 'objects/Character';

class Introduction extends Phaser.State {

  constructor() {
    super();
  }

  create() {
      this.game.physics.startSystem(Phaser.Physics.ARCADE);
      // Add the physics engine to all game objects
      this.game.world.enableBody = true;

      this.map = this.game.add.tilemap("level1");
      this.map.addTilesetImage(Levels[`Level${this.indexLevel}`].key, Tileset.key);

      this.map.createLayer('thirdLayer');
      this.map.createLayer('secondLayer');
      this.map.createLayer('firstLayer');
      // This resizes the game world to match the layer dimensions
      this.collisionLayer = this.map.createLayer('colissionLayer');
      this.map.setCollisionByExclusion([], true, this.collisionLayer);

      this.collisionLayer.resizeWorld();

      this.hero = new Character(this.game, Levels[`Level${this.indexLevel}`].playerPosition.x , Levels[`Level${this.indexLevel}`].playerPosition.y, HeroSprite.key, 0);
      this.game.add.existing(this.hero);
      this.game.camera.follow(this.hero);

      this.marker = null;
      this.createTileSelector();
      this.game.input.addMoveCallback(this.updateMarker, this);
  }

  preload() {
    this.game.load.spritesheet(HeroSprite.key, `res/${HeroSprite.path}`, WidthSpriteSheetHero, HeightSpriteSheetHero);
    this.game.load.image(Tileset.key, `res/${Tileset.path}`);
    this.game.load.tilemap("level1", "res/level1.json" , null, Phaser.Tilemap.TILED_JSON);
  }

  render() {
    //this.game.debug.text(this.game.time.fps, 2, 16, "#00ff00");
  }

}

export default Introduction;
<commit_msg>the view works now<commit_after>import { WidthSpriteSheetHero, HeightSpriteSheetHero, Width, Height } from '../Constants.js';
import { Tileset, Levels, HeroSprite } from '../ConstantsKey.js';
import MapManager from "objects/MapManager";
import Character from 'objects/Character';

class Introduction extends Phaser.State {

  constructor() {
    super();
  }

  create() {
      this.game.physics.startSystem(Phaser.Physics.ARCADE);
      // Add the physics engine to all game objects
      this.game.world.enableBody = true;

      this.map = this.game.add.tilemap(Levels[`Level1`].key);
      this.map.addTilesetImage(Levels[`Level1`].key, Tileset.key);

      this.map.createLayer('thirdLayer');
      this.map.createLayer('secondLayer');
      this.map.createLayer('firstLayer');
      // This resizes the game world to match the layer dimensions
      this.collisionLayer = this.map.createLayer('colissionLayer');
      this.map.setCollisionByExclusion([], true, this.collisionLayer);

      this.collisionLayer.resizeWorld();

      this.mapManager = new MapManager(this.map, Levels[`Level1`].lastLayer);
      this.mapManager.setUpCollisionLayer(this.collisionLayer);
  }

  preload() {
    this.game.load.spritesheet(HeroSprite.key, `res/${HeroSprite.path}`, WidthSpriteSheetHero, HeightSpriteSheetHero);
    this.game.load.image(Tileset.key, `res/${Tileset.path}`);
    this.game.load.tilemap(Levels[`Level1`].key, `res/${Levels[`Level1`].path}` , null, Phaser.Tilemap.TILED_JSON);
  }

  render() {
    //this.game.debug.text(this.game.time.fps, 2, 16, "#00ff00");
  }

}

export default Introduction;
<|endoftext|>


<commit_before>import request from 'superagent';
import * as ACTIONS from '../constants/action-types.js';
import { LIVE_SITE, LOCALHOST } from '../constants/urls.js';
import { isLoading, hasStoppedLoading } from './main-actions.js';

function addContractorSuccessful() {
  return {
    type: ACTIONS.ADD_CONTRACTOR
  };
}

function addContractorFailed(error) {
  return {
    type: ACTIONS.ADD_CONTRACTOR_FAILED,
    error
  };
}

function editContractorSuccessful() {
  return {
    type: ACTIONS.EDIT_CONTRACTOR
  };
}

function editContractorFailed(error) {
  return {
    type: ACTIONS.EDIT_CONTRACTOR_FAILED,
    error
  };
}

function viewContractorSuccessful(data) {
  return {
    type: ACTIONS.VIEW_CONTRACTORS,
    data
  };
}

function viewContractorFailed(error) {
  return {
    type: ACTIONS.VIEW_CONTRACTORS_FAILED,
    error
  };
}

function viewAllDataFailed(error) {
  return {
    type: ACTIONS.VIEW_ALL_DATA_FAILED,
    error
  };
}

function viewAllData(data) {
  return {
    type: ACTIONS.VIEW_ALL_DATA,
    data
  };
}

export function addContractor(contractorData, projectData, tableData, callback) {
  return dispatch => {
    dispatch(isLoading());
    return request
      .post(`${LIVE_SITE}contractors/add`)
      .query(contractorData)
      .then((res) => {
        const body = res.body;
        if (!res.ok || body.error) {
          throw new Error(body.errorMessage);
        }

        let contractorId = body.contractors[0].id;
        return contractorId;
      })
      .then((contractorId) => {
        return addEngagementContract(projectData, contractorId, tableData);
      })
      .then((responses) => {
        for(let res of responses) {
          let body = res.body;
          if(!res.ok || body.error) {
            throw new Error(body.errorMessage);
          }
        }
        dispatch(hasStoppedLoading());
        dispatch(addContractorSuccessful());
        callback();
      })
      .catch((err) => {
        dispatch(hasStoppedLoading());
        dispatch(addContractorFailed(err.message));
        callback();
      });
  };
}

function addEngagementContract(projectData, contractorId, tableData) {
   let allEngagementPromises = [];
   for(let project of projectData) {
       project["contractorId"] = contractorId;
       project["resourceId"] = "";
       project = conformDropdownValuesToDefault(project, tableData);
       let req = request
        .post(`${LIVE_SITE}contractors/add/engagementContract`)
        .query(project);
       allEngagementPromises.push(req);
   }

   return Promise.all(allEngagementPromises);
}

function conformDropdownValuesToDefault (project, tableData) {
  //todo change this to less hacky fix
  const REQUIRED_FIELDS = {"hrPositionId": "hrroles",
                          "hrPayGradeId": "paygrades",
                          "costCenterId": "costcenters",
                          "reportingManagerId": "hiringmanagers",
                          "mainSkillId": "skills",
                          "poNum": "refnos",
                          "rateType": "ratetypes"};
  for(let reqField in REQUIRED_FIELDS) {
    let actualFieldName = REQUIRED_FIELDS[reqField];
    if(!project.hasOwnProperty(reqField)){
      if(tableData.hasOwnProperty(actualFieldName)) {
        project[reqField] = tableData[actualFieldName].data[0].id;
      } else {
        project[reqField] = project[actualFieldName][0];
      }
    }
  }

  return project;
}

export function editContractor(data) {
  return dispatch => {
    dispatch(isLoading());
    return request
      .post(`${LIVE_SITE}contractors/edit`)
      .query(data)
      .then((res) => {
        const body = res.body;
        if (!res.ok || body.error) {
          throw new Error(body.errorMessage);
        }
        dispatch(hasStoppedLoading());
        dispatch(editContractorSuccessful());
      }).catch((err) => {
        dispatch(hasStoppedLoading());
        dispatch(editContractorFailed(err.message));
      });
  };
}

export function viewContractors() {
  return dispatch => {
    dispatch(isLoading());
    return request
      .get(`${LIVE_SITE}contractors/view`)
      .then((res) => {
        const body = res.body;
        if (!res.ok || body.error) {
          throw new Error(body.errorMessage);
        }
        dispatch(hasStoppedLoading());
        dispatch(viewContractorSuccessful(body.contractors));
      }).catch((err) => {
        dispatch(hasStoppedLoading());
        dispatch(viewContractorFailed(err.message));
      });
  };
}

export function viewAllContractorData() {
  return dispatch => {
    return request
      .get(`${LOCALHOST}contractors/viewAllData`)
      .then((res) => {
        const body = res.body;
        if (!res.ok || body.error) {
          throw new Error(body.errorMessage);
        }
        let contractors = body.contractors.map(c => {return flattenData(c)});
        dispatch(viewAllData(contractors));
      })
      .catch((err) => {
        dispatch(viewAllDataFailed(err.message));
      });
  };
}

//taken from https://stackoverflow.com/questions/19098797/fastest-way-to-flatten-un-flatten-nested-json-objects/19101235#19101235
function flattenData(data) {
  var result = {};
  function recurse (cur, prop) {
    if (Object(cur) !== cur) {
      result[prop] = cur;
    } else if (Array.isArray(cur)) {
      for(var i=0, l=cur.length; i<l; i++)
        recurse(cur[i], prop + "_");
      if (l == 0)
        result[prop] = [];
    } else {
      var isEmpty = true;
      for (var p in cur) {
        isEmpty = false;
        recurse(cur[p], prop ? prop +p : p);
      }
      if (isEmpty && prop)
        result[prop] = {};
    }
  }
  recurse(data, "");
  return result;
}
<commit_msg>changed localhost to live_site<commit_after>import request from 'superagent';
import * as ACTIONS from '../constants/action-types.js';
import { LIVE_SITE, LOCALHOST } from '../constants/urls.js';
import { isLoading, hasStoppedLoading } from './main-actions.js';

function addContractorSuccessful() {
  return {
    type: ACTIONS.ADD_CONTRACTOR
  };
}

function addContractorFailed(error) {
  return {
    type: ACTIONS.ADD_CONTRACTOR_FAILED,
    error
  };
}

function editContractorSuccessful() {
  return {
    type: ACTIONS.EDIT_CONTRACTOR
  };
}

function editContractorFailed(error) {
  return {
    type: ACTIONS.EDIT_CONTRACTOR_FAILED,
    error
  };
}

function viewContractorSuccessful(data) {
  return {
    type: ACTIONS.VIEW_CONTRACTORS,
    data
  };
}

function viewContractorFailed(error) {
  return {
    type: ACTIONS.VIEW_CONTRACTORS_FAILED,
    error
  };
}

function viewAllDataFailed(error) {
  return {
    type: ACTIONS.VIEW_ALL_DATA_FAILED,
    error
  };
}

function viewAllData(data) {
  return {
    type: ACTIONS.VIEW_ALL_DATA,
    data
  };
}

export function addContractor(contractorData, projectData, tableData, callback) {
  return dispatch => {
    dispatch(isLoading());
    return request
      .post(`${LIVE_SITE}contractors/add`)
      .query(contractorData)
      .then((res) => {
        const body = res.body;
        if (!res.ok || body.error) {
          throw new Error(body.errorMessage);
        }

        let contractorId = body.contractors[0].id;
        return contractorId;
      })
      .then((contractorId) => {
        return addEngagementContract(projectData, contractorId, tableData);
      })
      .then((responses) => {
        for(let res of responses) {
          let body = res.body;
          if(!res.ok || body.error) {
            throw new Error(body.errorMessage);
          }
        }
        dispatch(hasStoppedLoading());
        dispatch(addContractorSuccessful());
        callback();
      })
      .catch((err) => {
        dispatch(hasStoppedLoading());
        dispatch(addContractorFailed(err.message));
        callback();
      });
  };
}

function addEngagementContract(projectData, contractorId, tableData) {
   let allEngagementPromises = [];
   for(let project of projectData) {
       project["contractorId"] = contractorId;
       project["resourceId"] = "";
       project = conformDropdownValuesToDefault(project, tableData);
       let req = request
        .post(`${LIVE_SITE}contractors/add/engagementContract`)
        .query(project);
       allEngagementPromises.push(req);
   }

   return Promise.all(allEngagementPromises);
}

function conformDropdownValuesToDefault (project, tableData) {
  //todo change this to less hacky fix
  const REQUIRED_FIELDS = {"hrPositionId": "hrroles",
                          "hrPayGradeId": "paygrades",
                          "costCenterId": "costcenters",
                          "reportingManagerId": "hiringmanagers",
                          "mainSkillId": "skills",
                          "poNum": "refnos",
                          "rateType": "ratetypes"};
  for(let reqField in REQUIRED_FIELDS) {
    let actualFieldName = REQUIRED_FIELDS[reqField];
    if(!project.hasOwnProperty(reqField)){
      if(tableData.hasOwnProperty(actualFieldName)) {
        project[reqField] = tableData[actualFieldName].data[0].id;
      } else {
        project[reqField] = project[actualFieldName][0];
      }
    }
  }

  return project;
}

export function editContractor(data) {
  return dispatch => {
    dispatch(isLoading());
    return request
      .post(`${LIVE_SITE}contractors/edit`)
      .query(data)
      .then((res) => {
        const body = res.body;
        if (!res.ok || body.error) {
          throw new Error(body.errorMessage);
        }
        dispatch(hasStoppedLoading());
        dispatch(editContractorSuccessful());
      }).catch((err) => {
        dispatch(hasStoppedLoading());
        dispatch(editContractorFailed(err.message));
      });
  };
}

export function viewContractors() {
  return dispatch => {
    dispatch(isLoading());
    return request
      .get(`${LIVE_SITE}contractors/view`)
      .then((res) => {
        const body = res.body;
        if (!res.ok || body.error) {
          throw new Error(body.errorMessage);
        }
        dispatch(hasStoppedLoading());
        dispatch(viewContractorSuccessful(body.contractors));
      }).catch((err) => {
        dispatch(hasStoppedLoading());
        dispatch(viewContractorFailed(err.message));
      });
  };
}

export function viewAllContractorData() {
  return dispatch => {
    return request
      .get(`${LIVE_SITE}contractors/viewAllData`)
      .then((res) => {
        const body = res.body;
        if (!res.ok || body.error) {
          throw new Error(body.errorMessage);
        }
        let contractors = body.contractors.map(c => {return flattenData(c)});
        dispatch(viewAllData(contractors));
      })
      .catch((err) => {
        dispatch(viewAllDataFailed(err.message));
      });
  };
}

//taken from https://stackoverflow.com/questions/19098797/fastest-way-to-flatten-un-flatten-nested-json-objects/19101235#19101235
function flattenData(data) {
  var result = {};
  function recurse (cur, prop) {
    if (Object(cur) !== cur) {
      result[prop] = cur;
    } else if (Array.isArray(cur)) {
      for(var i=0, l=cur.length; i<l; i++)
        recurse(cur[i], prop + "_");
      if (l == 0)
        result[prop] = [];
    } else {
      var isEmpty = true;
      for (var p in cur) {
        isEmpty = false;
        recurse(cur[p], prop ? prop +p : p);
      }
      if (isEmpty && prop)
        result[prop] = {};
    }
  }
  recurse(data, "");
  return result;
}
<|endoftext|>


<commit_before><commit_msg>Update game.js<commit_after><|endoftext|>


<commit_before><commit_msg>changing init.js<commit_after><|endoftext|>


<commit_before>/**
 * Created by Simon on 25.05.2017.
 */
import { Meteor } from 'meteor/meteor';

import { MailFactory } from './MailFactory'
import { GlobalSettings } from '../config/GlobalSettings'
import {UserRoles as userroles} from "../userroles";
import {MeetingSeries} from "../meetingseries";

export class RoleChangeMailHandler {
    constructor(userId, oldRole, newRole, moderator, meetingSeriesId) {
        this._oldRole = oldRole;
        this._newRole = newRole;
        this._moderator = moderator;
        this._meetingSeriesId = meetingSeriesId;
        this._user = Meteor.users.findOne(userId);
        if (!this._user) {
            throw new Meteor.Error("Send Role Change Mail", "Could not find user: "+ userId);
        }
    }

    send() {
        let emailFrom = this._moderator.emails;
        let modFrom = (emailFrom && emailFrom.length > 0)
            ? emailFrom[0].address
            : GlobalSettings.getDefaultEmailSenderAddress();
        let emailTo = this._user.emails[0].address;

        // set parameter
        let meetingSeries = new MeetingSeries(this._meetingSeriesId)
        let meetingName = meetingSeries.name;

        let userName = "";
        if(this._user.profile === undefined) {
            userName = this._user.username;
        } else {
            userName =  this._user.profile.name;
        }

        if(this._oldRole == undefined) {
            this._oldRole = "None";
        } else {
            this._oldRole = userroles.role2Text(this._oldRole);
        }

        if(this._newRole == undefined) {
            this._newRole = "None";
        } else {
            this._newRole = userroles.role2Text(this._newRole);
        }

        // generate mail
        if (this._user.emails && this._user.emails.length > 0) {
            let mailer = MailFactory.getMailer(modFrom, emailTo);
            mailer.setSubject("Your role changed");
            mailer.setText("Hello " + userName + ", \n"+
                "Your role was changed in the meeting series \"" + meetingName + "\" (" + GlobalSettings.getRootUrl("meetingseries/" + this._meetingSeriesId) + ")\n"+
                "Your old role was           : " + this._oldRole + "\n"+
                "Your new role is            : " + this._newRole + "\n"+
                "The change was performed by : " + this._moderator.username + "\n"  +

                "\n" +
                "Your Admin.\n" +
                "\n" +
                "--- \n" +
                "4Minitz is free open source developed by the 4Minitz team.\n" +
                "Source is available at https://github.com/4minitz/4minitz\n"
            );

            mailer.send();
        } else {
            console.error("Could not send role change mail. User has no mail address: "+this._user._id);
        }
    }
}<commit_msg>Changed wording of error message<commit_after>/**
 * Created by Simon on 25.05.2017.
 */
import { Meteor } from 'meteor/meteor';

import { MailFactory } from './MailFactory'
import { GlobalSettings } from '../config/GlobalSettings'
import {UserRoles as userroles} from "../userroles";
import {MeetingSeries} from "../meetingseries";

export class RoleChangeMailHandler {
    constructor(userId, oldRole, newRole, moderator, meetingSeriesId) {
        this._oldRole = oldRole;
        this._newRole = newRole;
        this._moderator = moderator;
        this._meetingSeriesId = meetingSeriesId;
        this._user = Meteor.users.findOne(userId);
        if (!this._user) {
            throw new Meteor.Error("Send Role Change Mail", "Could not find user: "+ userId);
        }
    }

    send() {
        let emailFrom = this._moderator.emails;
        let modFrom = (emailFrom && emailFrom.length > 0)
            ? emailFrom[0].address
            : GlobalSettings.getDefaultEmailSenderAddress();
        let emailTo = this._user.emails[0].address;

        // set parameter
        let meetingSeries = new MeetingSeries(this._meetingSeriesId)
        let meetingName = meetingSeries.name;

        let userName = "";
        if(this._user.profile === undefined) {
            userName = this._user.username;
        } else {
            userName =  this._user.profile.name;
        }

        if(this._oldRole == undefined) {
            this._oldRole = "None";
        } else {
            this._oldRole = userroles.role2Text(this._oldRole);
        }

        if(this._newRole == undefined) {
            this._newRole = "None";
        } else {
            this._newRole = userroles.role2Text(this._newRole);
        }

        // generate mail
        if (this._user.emails && this._user.emails.length > 0) {
            let mailer = MailFactory.getMailer(modFrom, emailTo);
            mailer.setSubject("Your role changed");
            mailer.setText("Hello " + userName + ", \n"+
                "Your role was changed in the meeting series \"" + meetingName + "\" (" + GlobalSettings.getRootUrl("meetingseries/" + this._meetingSeriesId) + ")\n"+
                "Your old role was           : " + this._oldRole + "\n"+
                "Your new role is            : " + this._newRole + "\n"+
                "The change was performed by : " + this._moderator.username + "\n"  +

                "\n" +
                "Your Admin.\n" +
                "\n" +
                "--- \n" +
                "4Minitz is free open source developed by the 4Minitz team.\n" +
                "Source is available at https://github.com/4minitz/4minitz\n"
            );

            mailer.send();
        } else {
            console.error("Could not send eMail for role change. User has no mail address: "+this._user._id);
        }
    }
}<|endoftext|>


<commit_before>var GameState = function(){
    this.STATE_SPLASH = 0;
    this.STATE_GAME = 1;
    this.STATE_GAMEOVER = 2;
    this.STATE_MAIN_MENU = 3;
    this.STATE_HIGH_SCORES = 4;

    this.state = 0;
    console.log(this.state);
}

GameState.prototype.setState = function(state)
{
    this.state = state;
};
<commit_msg>remove console.log<commit_after>var GameState = function(){
    this.STATE_SPLASH = 0;
    this.STATE_GAME = 1;
    this.STATE_GAMEOVER = 2;
    this.STATE_MAIN_MENU = 3;
    this.STATE_HIGH_SCORES = 4;

    this.state = 0;
}

GameState.prototype.setState = function(state)
{
    this.state = state;
};
<|endoftext|>


<commit_before>/* jshint node:true */

'use strict';

module.exports = function(grunt) {

  require('load-grunt-tasks')(grunt);

  // Default task.
  grunt.registerTask('default', ['test']);
  grunt.registerTask('test', ['jshint', 'karma:unit']);
  grunt.registerTask('serve', ['karma:continuous', 'dist', 'build:gh-pages', 'connect:continuous', 'watch']);
  grunt.registerTask('dist', ['ngmin', 'surround', 'uglify' ]);
  grunt.registerTask('coverage', ['jshint', 'karma:coverage']);
  grunt.registerTask('junit', ['jshint', 'karma:junit']);

  // HACK TO ACCESS TO THE COMPONENT PUBLISHER
  function fakeTargetTask(prefix){
    return function(){

      if (this.args.length !== 1) {
        return grunt.log.fail('Just give the name of the ' + prefix + ' you want like :\ngrunt ' + prefix + ':bower');
      }

      var done = this.async();
      var spawn = require('child_process').spawn;
      spawn('./node_modules/.bin/gulp', [ prefix, '--branch='+this.args[0] ].concat(grunt.option.flags()), {
        cwd : './node_modules/angular-ui-publisher',
        stdio: 'inherit'
      }).on('close', done);
    };
  }

  grunt.registerTask('build', fakeTargetTask('build'));
  grunt.registerTask('publish', fakeTargetTask('publish'));
  //

  // HACK TO MAKE TRAVIS WORK
  var testConfig = function(configFile, customOptions) {
    var options = { configFile: configFile, singleRun: true };
    var travisOptions = process.env.TRAVIS && {
      browsers: ['Firefox', 'PhantomJS'],
      reporters: ['dots', 'coverage', 'coveralls'],
      preprocessors: { 'src/*.js': ['coverage'] },
      coverageReporter: {
        reporters: [{
          type: 'text'
        }, {
          type: 'lcov',
          dir: 'coverage/'
        }]
      },
    };
    return grunt.util._.extend(options, customOptions, travisOptions);
  };
  //

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    meta: {
      banner: ['/**',
        ' * <%= pkg.name %> - <%= pkg.description %>',
        ' * @version v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>',
        ' * @link <%= pkg.homepage %>',
        ' * @license <%= pkg.license %>',
        ' */',
        ''].join('\n')
    },

    connect: {
      options: {
        base : 'out/built/gh-pages',
        open: true,
        livereload: true
      },
      server: { options: { keepalive: true } },
      continuous: { options: { keepalive: false } }
    },

    coveralls: {
      options: {
        coverage_dir: 'coverage/',
        // debug: true
        // dryRun: true,
        // force: true,
        // recursive: true
      }
    },

    karma: {
      unit: testConfig('test/karma.conf.js'),
      server: {configFile: 'test/karma.conf.js'},
      continuous: {configFile: 'test/karma.conf.js',  background: true },
      coverage: {
        configFile: 'test/karma.conf.js',
        reporters: ['progress', 'coverage'],
        preprocessors: { 'src/*.js': ['coverage'] },
        coverageReporter: {
          reporters: [{
            type: 'text'
          }, {
            type: 'lcov',
            dir: 'coverage/'
          }]
        },
        singleRun: true
      },
      junit: {
        configFile: 'test/karma.conf.js',
        reporters: ['progress', 'junit'],
        junitReporter: {
          outputFile: 'junit/unit.xml',
          suite: 'unit'
        },
        singleRun: true
      }
    },

    jshint: {
      src: {
        files:{ src : ['src/**/*.js', 'demo/**/*.js'] },
        options: { jshintrc: '.jshintrc' }
      },
      test: {
        files:{ src : [ 'test/*.js', 'gruntFile.js'] },
        options: grunt.util._.extend({}, grunt.file.readJSON('.jshintrc'), grunt.file.readJSON('test/.jshintrc'))
      }
    },

    uglify: {
      build: {
        expand: true,
        cwd: 'dist',
        src: ['*.js', '!*.min.js'],
        ext: '.min.js',
        dest: 'dist'
      }
    },

    surround: {
      options: {
        prepend: ['(function(window, angular, undefined) {',
                  '\'use strict\';'].join('\n'),
        append: '})(window, window.angular);'
      },
      main: {
        expand: true,
        cwd: 'src',
        src: ['*.js'],
        dest: 'dist'
      }
    },

    ngmin: {
      main: {
        expand: true,
        cwd: 'src',
        src: ['*.js'],
        dest: 'dist'
      }
    },

    changelog: {
      options: {
        dest: 'CHANGELOG.md'
      }
    },

    watch: {
      src: {
        files: ['src/*'],
        tasks: ['jshint:src', 'karma:unit:run', 'dist', 'build:gh-pages']
      },
      test: {
        files: ['test/*.js'],
        tasks: ['jshint:test', 'karma:unit:run']
      },
      demo: {
        files: ['demo/*', 'publish.js'],
        tasks: ['jshint', 'build:gh-pages']
      },
      livereload: {
        files: ['out/built/gh-pages/**/*'],
        options: { livereload: true }
      }
    }
  });

};
<commit_msg>chore: use Chrome and Firefox on Travis, since PhantomJS was inconsistent<commit_after>/* jshint node:true */

'use strict';

module.exports = function(grunt) {

  require('load-grunt-tasks')(grunt);

  // Default task.
  grunt.registerTask('default', ['test']);
  grunt.registerTask('test', ['jshint', 'karma:unit']);
  grunt.registerTask('serve', ['karma:continuous', 'dist', 'build:gh-pages', 'connect:continuous', 'watch']);
  grunt.registerTask('dist', ['ngmin', 'surround', 'uglify' ]);
  grunt.registerTask('coverage', ['jshint', 'karma:coverage']);
  grunt.registerTask('junit', ['jshint', 'karma:junit']);

  // HACK TO ACCESS TO THE COMPONENT PUBLISHER
  function fakeTargetTask(prefix){
    return function(){

      if (this.args.length !== 1) {
        return grunt.log.fail('Just give the name of the ' + prefix + ' you want like :\ngrunt ' + prefix + ':bower');
      }

      var done = this.async();
      var spawn = require('child_process').spawn;
      spawn('./node_modules/.bin/gulp', [ prefix, '--branch='+this.args[0] ].concat(grunt.option.flags()), {
        cwd : './node_modules/angular-ui-publisher',
        stdio: 'inherit'
      }).on('close', done);
    };
  }

  grunt.registerTask('build', fakeTargetTask('build'));
  grunt.registerTask('publish', fakeTargetTask('publish'));
  //

  // HACK TO MAKE TRAVIS WORK
  var testConfig = function(configFile, customOptions) {
    var options = { configFile: configFile, singleRun: true };
    var travisOptions = process.env.TRAVIS && {
      browsers: ['Chrome', 'Firefox'],
      reporters: ['dots', 'coverage', 'coveralls'],
      preprocessors: { 'src/*.js': ['coverage'] },
      coverageReporter: {
        reporters: [{
          type: 'text'
        }, {
          type: 'lcov',
          dir: 'coverage/'
        }]
      },
    };
    return grunt.util._.extend(options, customOptions, travisOptions);
  };
  //

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    meta: {
      banner: ['/**',
        ' * <%= pkg.name %> - <%= pkg.description %>',
        ' * @version v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>',
        ' * @link <%= pkg.homepage %>',
        ' * @license <%= pkg.license %>',
        ' */',
        ''].join('\n')
    },

    connect: {
      options: {
        base : 'out/built/gh-pages',
        open: true,
        livereload: true
      },
      server: { options: { keepalive: true } },
      continuous: { options: { keepalive: false } }
    },

    coveralls: {
      options: {
        coverage_dir: 'coverage/',
        // debug: true
        // dryRun: true,
        // force: true,
        // recursive: true
      }
    },

    karma: {
      unit: testConfig('test/karma.conf.js'),
      server: {configFile: 'test/karma.conf.js'},
      continuous: {configFile: 'test/karma.conf.js',  background: true },
      coverage: {
        configFile: 'test/karma.conf.js',
        reporters: ['progress', 'coverage'],
        preprocessors: { 'src/*.js': ['coverage'] },
        coverageReporter: {
          reporters: [{
            type: 'text'
          }, {
            type: 'lcov',
            dir: 'coverage/'
          }]
        },
        singleRun: true
      },
      junit: {
        configFile: 'test/karma.conf.js',
        reporters: ['progress', 'junit'],
        junitReporter: {
          outputFile: 'junit/unit.xml',
          suite: 'unit'
        },
        singleRun: true
      }
    },

    jshint: {
      src: {
        files:{ src : ['src/**/*.js', 'demo/**/*.js'] },
        options: { jshintrc: '.jshintrc' }
      },
      test: {
        files:{ src : [ 'test/*.js', 'gruntFile.js'] },
        options: grunt.util._.extend({}, grunt.file.readJSON('.jshintrc'), grunt.file.readJSON('test/.jshintrc'))
      }
    },

    uglify: {
      build: {
        expand: true,
        cwd: 'dist',
        src: ['*.js', '!*.min.js'],
        ext: '.min.js',
        dest: 'dist'
      }
    },

    surround: {
      options: {
        prepend: ['(function(window, angular, undefined) {',
                  '\'use strict\';'].join('\n'),
        append: '})(window, window.angular);'
      },
      main: {
        expand: true,
        cwd: 'src',
        src: ['*.js'],
        dest: 'dist'
      }
    },

    ngmin: {
      main: {
        expand: true,
        cwd: 'src',
        src: ['*.js'],
        dest: 'dist'
      }
    },

    changelog: {
      options: {
        dest: 'CHANGELOG.md'
      }
    },

    watch: {
      src: {
        files: ['src/*'],
        tasks: ['jshint:src', 'karma:unit:run', 'dist', 'build:gh-pages']
      },
      test: {
        files: ['test/*.js'],
        tasks: ['jshint:test', 'karma:unit:run']
      },
      demo: {
        files: ['demo/*', 'publish.js'],
        tasks: ['jshint', 'build:gh-pages']
      },
      livereload: {
        files: ['out/built/gh-pages/**/*'],
        options: { livereload: true }
      }
    }
  });

};
<|endoftext|>