<commit_before>'use strict';

require('app/stylesheets/mapbox-gl.css');

import mapboxgl from 'mapbox-gl/dist/mapbox-gl.js';
import React, { Component, PropTypes } from 'react';
import { colors, dimensions, mapbox, mapMarkers } from 'app/constants';

class TripMapDisplay extends Component {
  componentDidMount() {
    this.map = this.loadMap();
    this.map.on('load', () => this.loadSourceData());
    this.fitMapToData(true);
  }

  // Update the map markers if there are any changes
  componentWillReceiveProps(newProps) {
    const { focusLngLat, ideas, hoverLngLat } = this.props;
    const { map } = this;
    const {
      fitMapRequest,
      focusLngLat: newFocusLngLat,
      focusMarker,
      ideas: newIdeas,
      hoverLngLat: newHoverLngLat,
      mapStyleURL,
      onDeleteFocusMarker,
      onMapFitComplete,
      onViewUpdated,
      viewChanged
    } = newProps;

    if (viewChanged) {
      map.setStyle(mapStyleURL);
      map.on('style.load', () => {
        !map.getSource(mapbox.ids.markers) && this.loadSourceData();
      });

      onViewUpdated();
    }

    if (newIdeas.length !== ideas.length) {
      map
        .getSource(mapbox.ids.markers)
        .setData(createGeoJSON(newIdeas));
    }

    if (newHoverLngLat !== hoverLngLat) {
      this.loadHoverMarker(newProps);
    }

    if (newFocusLngLat !== focusLngLat) {
      this.loadFocusMarker(newProps);
    }

    if (fitMapRequest) {
      this.fitMapToData(fitMapRequest === 'destination');
      onMapFitComplete();
    }
  }

  render() {
    const { destination, ideas, onSetMapView, onSetSatelliteView } = this.props;
    const { mapOption, satelliteOption } = styles;

    const viewControl = (

          Map

🌎

          Satellite

    );

    return (

 this.container = x}
          style={styles.mapContainer}
        >
          {viewControl}

    );
  }

  loadMap() {
    const { mapStyleURL } = this.props;

    // Initialize the map and set it to the viewport of the destination
    mapboxgl.accessToken = mapbox.token;

    let map = new mapboxgl.Map({
      container: this.container,
      style: mapStyleURL,
      attributionControl: true,
      center: this.props.destination.loc.coordinates,
    });

    // Add zoom and rotation controls to the map.
    map.addControl(new mapboxgl.Navigation());
    return map;
  }

  loadSourceData() {
    const { ideas, trackIdeaView } = this.props;
    const { map } = this;
    const { hover, markers } = mapbox.ids;
    const moveMapToLocation = this.moveMapToLocation.bind(this);

    // Load the marker data into the map
    map.addSource(markers, {
      type: 'geojson',
      data: createGeoJSON(ideas)
    });

    // Add layers visualizing the markers and invisible hover targets
    map.addLayer(createLayerJSON(markers));
    map.addLayer(createLayerJSON(hover));

    const popup = new mapboxgl.Popup({
      closeButton: false,
      closeOnClick: false
    });

    // Create event handlers for displaying popups
    map.on('mousemove', e => showOrHidePopup(popup, e.point, map));
    map.on('click', e => {
      const feature = showOrHidePopup(popup, e.point, map);
      if (feature) {
        trackIdeaView(feature.properties._id);
        moveMapToLocation(feature.geometry.coordinates);
      }
    });
  }

  fitMapToData(boundToDestination) {
    const { destination, ideas } = this.props;
    const {
      southwest: { coordinates: swll },
      northeast: { coordinates: nell }
    } = destination.viewport;

    let bounds;
    if (boundToDestination) {
      bounds = new mapboxgl.LngLatBounds(swll, nell);
    } else {
      bounds = new mapboxgl.LngLatBounds();
    }

    if (ideas.length === 1 && !boundToDestination) {
      this.map.easeTo({
        center: ideas[0].loc.coordinates,
        zoom: 15
      });
    } else {
      // Ensure the bounds captures all the ideas' locations
      ideas.map(idea => bounds.extend(idea.loc.coordinates));
      this.map.fitBounds(bounds, {
        linear: boundToDestination,
        padding: 100,
        duration: 1000,
        offset: [dimensions.leftColumn.width / 2, 0],
        curve: 1,
        speed: 2,
        easing: easeInOutQuad
      });
    }
  }

  createHoverMarker(lngLat, isFocusMarker = false) {
    const { onSaveFocusMarker, onSaveHoverMarker } = this.props;

    let markerElem = document.createElement('div');
    markerElem.className = 'hover-marker';
    markerElem.style.backgroundImage = isFocusMarker ?
      'url("../assets/marker-icon-focus.png")' :
      'url("../assets/marker-icon.png")';
    markerElem.style.width = mapMarkers.icon.width;
    markerElem.style.height = mapMarkers.icon.height;

    const marker = new mapboxgl.Marker(
      markerElem,
      { offset: [-mapMarkers.icon.width/2, -mapMarkers.icon.height] }
    )
      .setLngLat(lngLat)
      .addTo(this.map);

    isFocusMarker ? onSaveFocusMarker(marker) : onSaveHoverMarker(marker);
  }

  loadHoverMarker(props) {
    const {
      focusLngLat,
      focusMarker,
      hoverMarker,
      ideas,
      hoverLngLat,
      onClearFocusLngLat,
      onDeleteFocusMarker,
      onDeleteHoverMarker
    } = props;

    if (hoverMarker) {
      onDeleteHoverMarker(hoverMarker);
    }

    if (hoverLngLat && hoverLngLat !== focusLngLat) {
      focusLngLat && onClearFocusLngLat();
      this.createHoverMarker(hoverLngLat);
    }
  }

  createFocusMarker(lngLat) {
    this.createHoverMarker(lngLat, true);
  }

  loadFocusMarker(props) {
    const {
      focusMarker,
      focusLngLat,
      hoverMarker,
      ideas,
      onDeleteFocusMarker,
      onDeleteHoverMarker
    } = props;

    if (focusMarker) {
      onDeleteFocusMarker(focusMarker);
    }

    if (focusLngLat) {
      hoverMarker && onDeleteHoverMarker(hoverMarker);
      this.createFocusMarker(focusLngLat);
      this.moveMapToLocation(focusLngLat);
    }
  }

  moveMapToLocation(lngLat) {
    const opts = {
      center: lngLat,
      offset: [dimensions.leftColumn.width / 2, 0],
      zoom: 15
    };

    if (this.map.getZoom() >= 15) {
      opts.duration = 300;
      this.map.easeTo(opts);
    } else {
      opts.speed = 2;
      opts.easing = easeInOutQuad;
      this.map.flyTo(opts);
    }
  }

  loadOptionStyle(style, option) {
    const { mapStyle } = this.props;

    if (mapStyle === option) {
      return { ...style, backgroundColor: "#eeeeee" };
    }

    return style;
  }
}

function createGeoJSON(ideas) {
  return {
    type: 'FeatureCollection',
    features: ideas.map(idea => createSourceEntry(idea))
  };
}

function createLayerJSON(name) {
  const { hover, markers } = mapbox.ids;
  let blur = name === markers ? 0.4 : 0;
  let color = name === markers ? colors.primary : "rgba(0, 0, 0, 0)";
  let radius = name === markers ? 8 : 15;

  return {
    id: name,
    type: 'circle',
    source: markers,
    paint: {
      "circle-radius": radius,
      "circle-color": color,
      "circle-blur": blur
    }
  };
}

function createSourceEntry(idea) {
  const { _id, name, photo, address, loc } = idea;
  const properties = { _id, name, photo, address };
  const geometry = loc;

  return {
    type: "Feature",
    properties,
    geometry
  };
}

function createPopupHTML(idea) {
  let popupHTML = idea.photo ? `<img src="${idea.photo}">` : '';
  popupHTML += `

${idea.name}

${idea.address}
`;

  return popupHTML;
}

function showOrHidePopup(popup, point, map) {
  const { hover } = mapbox.ids;
  const features = map.queryRenderedFeatures(point, { layers: [hover] });

  // Change the cursor style as a UI indicator.
  map.getCanvas().style.cursor = (features.length) ? 'pointer' : '';

  if (!features.length) {
    popup.remove();
    return;
  }

  // Add popup to map if the user hovers over a marker
  const feature = features[0];
  popup
    .setLngLat(feature.geometry.coordinates)
    .setHTML(createPopupHTML(feature.properties))
    .addTo(map);

  return feature;
}

function easeInOutQuad(t) {
  return t<.5 ? 2*t*t : -1+2*(2-t)*t;
}

TripMapDisplay.propTypes = {
  destination: PropTypes.object,
  fitMapRequest: PropTypes.string,
  focusLngLat: PropTypes.array,
  focusMarker: PropTypes.object,
  hoverLngLat: PropTypes.array,
  hoverMarker: PropTypes.object,
  ideas: PropTypes.array,
  mapStyle: PropTypes.string.isRequired,
  mapStyleURL: PropTypes.string.isRequired,
  onClearFocusLngLat: PropTypes.func.isRequired,
  onDeleteFocusMarker: PropTypes.func.isRequired,
  onDeleteHoverMarker: PropTypes.func.isRequired,
  onSaveFocusMarker: PropTypes.func.isRequired,
  onSaveHoverMarker: PropTypes.func.isRequired,
  onSetMapView: PropTypes.func.isRequired,
  onSetSatelliteView: PropTypes.func.isRequired,
  onViewUpdated: PropTypes.func.isRequired,
  trackIdeaView: PropTypes.func.isRequired,
  viewChanged: PropTypes.bool.isRequired
};

const styles = {
  earthEmoji: {
    fontSize: 20,
    fontWeight: "normal",
    marginTop: 5,
    position: "relative",
    top: 2
  },
  mapContainer: {
    position: "absolute",
    top: 0,
    bottom: 0,
    width: "100%",
    zIndex: 1
  },
  viewControl: {
    backgroundColor: "white",
    borderRadius: 4,
    boxShadow: "0px 0px 0px 2px rgba(0,0,0,0.1)",
    float: "right",
    height: 90,
    position: "relative",
    right: 50,
    top: 10,
    width: 60,
    zIndex: 1
  },
  mapIcon: {
    marginTop: 3,
    position: "relative",
    top: 1
  },
  mapOption: {
    alignItems: "center",
    borderBottom: "1px solid #dddddd",
    borderTopLeftRadius: 4,
    borderTopRightRadius: 4,
    cursor: "pointer",
    display: "flex",
    flexDirection: "column",
    fontSize: 11,
    fontWeight: 500,
    height: 45
  },
  satelliteOption: {
    alignItems: "center",
    borderBottomLeftRadius: 4,
    borderBottomRightRadius: 4,
    cursor: "pointer",
    display: "flex",
    flexDirection: "column",
    fontSize: 11,
    fontWeight: 500,
    height: 45
  }
};

export default TripMapDisplay;
<commit_msg>Display map labels in front of red markers<commit_after>'use strict';

require('app/stylesheets/mapbox-gl.css');

import mapboxgl from 'mapbox-gl/dist/mapbox-gl.js';
import React, { Component, PropTypes } from 'react';
import { colors, dimensions, mapbox, mapMarkers } from 'app/constants';

class TripMapDisplay extends Component {
  componentDidMount() {
    this.map = this.loadMap();
    this.map.on('load', () => this.loadSourceData());
    this.fitMapToData(true);
  }

  // Update the map markers if there are any changes
  componentWillReceiveProps(newProps) {
    const { focusLngLat, ideas, hoverLngLat } = this.props;
    const { map } = this;
    const {
      fitMapRequest,
      focusLngLat: newFocusLngLat,
      focusMarker,
      ideas: newIdeas,
      hoverLngLat: newHoverLngLat,
      mapStyleURL,
      onDeleteFocusMarker,
      onMapFitComplete,
      onViewUpdated,
      viewChanged
    } = newProps;

    if (viewChanged) {
      map.setStyle(mapStyleURL);
      map.on('style.load', () => {
        !map.getSource(mapbox.ids.markers) && this.loadSourceData();
      });

      onViewUpdated();
    }

    if (newIdeas.length !== ideas.length) {
      map
        .getSource(mapbox.ids.markers)
        .setData(createGeoJSON(newIdeas));
    }

    if (newHoverLngLat !== hoverLngLat) {
      this.loadHoverMarker(newProps);
    }

    if (newFocusLngLat !== focusLngLat) {
      this.loadFocusMarker(newProps);
    }

    if (fitMapRequest) {
      this.fitMapToData(fitMapRequest === 'destination');
      onMapFitComplete();
    }
  }

  render() {
    const { destination, ideas, onSetMapView, onSetSatelliteView } = this.props;
    const { mapOption, satelliteOption } = styles;

    const viewControl = (

          Map

🌎

          Satellite

    );

    return (

 this.container = x}
          style={styles.mapContainer}
        >
          {viewControl}

    );
  }

  loadMap() {
    const { mapStyleURL } = this.props;

    // Initialize the map and set it to the viewport of the destination
    mapboxgl.accessToken = mapbox.token;

    let map = new mapboxgl.Map({
      container: this.container,
      style: mapStyleURL,
      attributionControl: true,
      center: this.props.destination.loc.coordinates,
    });

    // Add zoom and rotation controls to the map.
    map.addControl(new mapboxgl.Navigation());
    return map;
  }

  loadSourceData() {
    const { ideas, trackIdeaView } = this.props;
    const { map } = this;
    const { hover, markers } = mapbox.ids;
    const moveMapToLocation = this.moveMapToLocation.bind(this);

    // Load the marker data into the map
    map.addSource(markers, {
      type: 'geojson',
      data: createGeoJSON(ideas)
    });

    // Add layers visualizing the markers and invisible hover targets
    map.addLayer(createLayerJSON(markers), 'housenum-label');
    map.addLayer(createLayerJSON(hover));

    const popup = new mapboxgl.Popup({
      closeButton: false,
      closeOnClick: false
    });

    // Create event handlers for displaying popups
    map.on('mousemove', e => showOrHidePopup(popup, e.point, map));
    map.on('click', e => {
      const feature = showOrHidePopup(popup, e.point, map);
      if (feature) {
        trackIdeaView(feature.properties._id);
        moveMapToLocation(feature.geometry.coordinates);
      }
    });
  }

  fitMapToData(boundToDestination) {
    const { destination, ideas } = this.props;
    const {
      southwest: { coordinates: swll },
      northeast: { coordinates: nell }
    } = destination.viewport;

    let bounds;
    if (boundToDestination) {
      bounds = new mapboxgl.LngLatBounds(swll, nell);
    } else {
      bounds = new mapboxgl.LngLatBounds();
    }

    if (ideas.length === 1 && !boundToDestination) {
      this.map.easeTo({
        center: ideas[0].loc.coordinates,
        zoom: 15
      });
    } else {
      // Ensure the bounds captures all the ideas' locations
      ideas.map(idea => bounds.extend(idea.loc.coordinates));
      this.map.fitBounds(bounds, {
        linear: boundToDestination,
        padding: 100,
        duration: 1000,
        offset: [dimensions.leftColumn.width / 2, 0],
        curve: 1,
        speed: 2,
        easing: easeInOutQuad
      });
    }
  }

  createHoverMarker(lngLat, isFocusMarker = false) {
    const { onSaveFocusMarker, onSaveHoverMarker } = this.props;

    let markerElem = document.createElement('div');
    markerElem.className = 'hover-marker';
    markerElem.style.backgroundImage = isFocusMarker ?
      'url("../assets/marker-icon-focus.png")' :
      'url("../assets/marker-icon.png")';
    markerElem.style.width = mapMarkers.icon.width;
    markerElem.style.height = mapMarkers.icon.height;

    const marker = new mapboxgl.Marker(
      markerElem,
      { offset: [-mapMarkers.icon.width/2, -mapMarkers.icon.height] }
    )
      .setLngLat(lngLat)
      .addTo(this.map);

    isFocusMarker ? onSaveFocusMarker(marker) : onSaveHoverMarker(marker);
  }

  loadHoverMarker(props) {
    const {
      focusLngLat,
      focusMarker,
      hoverMarker,
      ideas,
      hoverLngLat,
      onClearFocusLngLat,
      onDeleteFocusMarker,
      onDeleteHoverMarker
    } = props;

    if (hoverMarker) {
      onDeleteHoverMarker(hoverMarker);
    }

    if (hoverLngLat && hoverLngLat !== focusLngLat) {
      focusLngLat && onClearFocusLngLat();
      this.createHoverMarker(hoverLngLat);
    }
  }

  createFocusMarker(lngLat) {
    this.createHoverMarker(lngLat, true);
  }

  loadFocusMarker(props) {
    const {
      focusMarker,
      focusLngLat,
      hoverMarker,
      ideas,
      onDeleteFocusMarker,
      onDeleteHoverMarker
    } = props;

    if (focusMarker) {
      onDeleteFocusMarker(focusMarker);
    }

    if (focusLngLat) {
      hoverMarker && onDeleteHoverMarker(hoverMarker);
      this.createFocusMarker(focusLngLat);
      this.moveMapToLocation(focusLngLat);
    }
  }

  moveMapToLocation(lngLat) {
    const opts = {
      center: lngLat,
      offset: [dimensions.leftColumn.width / 2, 0],
      zoom: 15
    };

    if (this.map.getZoom() >= 15) {
      opts.duration = 300;
      this.map.easeTo(opts);
    } else {
      opts.speed = 2;
      opts.easing = easeInOutQuad;
      this.map.flyTo(opts);
    }
  }

  loadOptionStyle(style, option) {
    const { mapStyle } = this.props;

    if (mapStyle === option) {
      return { ...style, backgroundColor: "#eeeeee" };
    }

    return style;
  }
}

function createGeoJSON(ideas) {
  return {
    type: 'FeatureCollection',
    features: ideas.map(idea => createSourceEntry(idea))
  };
}

function createLayerJSON(name) {
  const { hover, markers } = mapbox.ids;
  let blur = name === markers ? 0.4 : 0;
  let color = name === markers ? colors.primary : "rgba(0, 0, 0, 0)";
  let radius = name === markers ? 8 : 15;

  return {
    id: name,
    type: 'circle',
    source: markers,
    paint: {
      "circle-radius": radius,
      "circle-color": color,
      "circle-blur": blur
    }
  };
}

function createSourceEntry(idea) {
  const { _id, name, photo, address, loc } = idea;
  const properties = { _id, name, photo, address };
  const geometry = loc;

  return {
    type: "Feature",
    properties,
    geometry
  };
}

function createPopupHTML(idea) {
  let popupHTML = idea.photo ? `<img src="${idea.photo}">` : '';
  popupHTML += `

${idea.name}

${idea.address}
`;

  return popupHTML;
}

function showOrHidePopup(popup, point, map) {
  const { hover } = mapbox.ids;
  const features = map.queryRenderedFeatures(point, { layers: [hover] });

  // Change the cursor style as a UI indicator.
  map.getCanvas().style.cursor = (features.length) ? 'pointer' : '';

  if (!features.length) {
    popup.remove();
    return;
  }

  // Add popup to map if the user hovers over a marker
  const feature = features[0];
  popup
    .setLngLat(feature.geometry.coordinates)
    .setHTML(createPopupHTML(feature.properties))
    .addTo(map);

  return feature;
}

function easeInOutQuad(t) {
  return t<.5 ? 2*t*t : -1+2*(2-t)*t;
}

TripMapDisplay.propTypes = {
  destination: PropTypes.object,
  fitMapRequest: PropTypes.string,
  focusLngLat: PropTypes.array,
  focusMarker: PropTypes.object,
  hoverLngLat: PropTypes.array,
  hoverMarker: PropTypes.object,
  ideas: PropTypes.array,
  mapStyle: PropTypes.string.isRequired,
  mapStyleURL: PropTypes.string.isRequired,
  onClearFocusLngLat: PropTypes.func.isRequired,
  onDeleteFocusMarker: PropTypes.func.isRequired,
  onDeleteHoverMarker: PropTypes.func.isRequired,
  onSaveFocusMarker: PropTypes.func.isRequired,
  onSaveHoverMarker: PropTypes.func.isRequired,
  onSetMapView: PropTypes.func.isRequired,
  onSetSatelliteView: PropTypes.func.isRequired,
  onViewUpdated: PropTypes.func.isRequired,
  trackIdeaView: PropTypes.func.isRequired,
  viewChanged: PropTypes.bool.isRequired
};

const styles = {
  earthEmoji: {
    fontSize: 20,
    fontWeight: "normal",
    marginTop: 5,
    position: "relative",
    top: 2
  },
  mapContainer: {
    position: "absolute",
    top: 0,
    bottom: 0,
    width: "100%",
    zIndex: 1
  },
  viewControl: {
    backgroundColor: "white",
    borderRadius: 4,
    boxShadow: "0px 0px 0px 2px rgba(0,0,0,0.1)",
    float: "right",
    height: 90,
    position: "relative",
    right: 50,
    top: 10,
    width: 60,
    zIndex: 1
  },
  mapIcon: {
    marginTop: 3,
    position: "relative",
    top: 1
  },
  mapOption: {
    alignItems: "center",
    borderBottom: "1px solid #dddddd",
    borderTopLeftRadius: 4,
    borderTopRightRadius: 4,
    cursor: "pointer",
    display: "flex",
    flexDirection: "column",
    fontSize: 11,
    fontWeight: 500,
    height: 45
  },
  satelliteOption: {
    alignItems: "center",
    borderBottomLeftRadius: 4,
    borderBottomRightRadius: 4,
    cursor: "pointer",
    display: "flex",
    flexDirection: "column",
    fontSize: 11,
    fontWeight: 500,
    height: 45
  }
};

export default TripMapDisplay;
<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Component.extend({
  tagName: 'div',
  classNames: ['loading-slider'],
  classNameBindings: 'expanding',

  initialize: Ember.on('didReceiveAttrs', function() {
    this.set('isLoading', this.getAttr('isLoading'));
    this.set('duration', this.getAttr('duration'));
    this.set('expanding', this.getAttr('expanding'));
    this.set('speed', this.getAttr('speed'));
    this.set('color', this.getAttr('color'));

    this.manage();
  }),

  manage() {
    if (this.get('isLoading')) {
      if (this.get('expanding')) {
        this.expandingAnimate.call(this);
      } else {
        this.animate.call(this);
      }
    } else {
      this.set('isLoaded', true);
    }
  },

  animate() {
    this.set('isLoaded', false);
    let self = this,
        elapsedTime = 0,
        inner = $('<span>'),
        outer = this.$(),
        duration = this.getWithDefault('duration', 300),
        innerWidth = 0,
        outerWidth = this.$().width(),
        stepWidth = Math.round(outerWidth / 50),
        color = this.get('color');

    outer.append(inner);
    if (color) {
      inner.css('background-color', color);
    }

    let interval = window.setInterval(function() {
      elapsedTime = elapsedTime + 10;
      inner.width(innerWidth = innerWidth + stepWidth);

      // slow the animation if we used more than 75% the estimated duration
      // or 66% of the animation width
      if (elapsedTime > (duration * 0.75) || innerWidth > (outerWidth * 0.66)) {
        // don't stop the animation completely
        if (stepWidth > 1) {
          stepWidth = stepWidth * 0.97;
        }
      }

      if (innerWidth > outerWidth) {
        Ember.run.later(function() {
          outer.empty();
          window.clearInterval(interval);
        }, 50);
      }

      // the activity has finished
      if (self.get('isLoaded')) {
        // start with a sizable pixel step
        if (stepWidth < 10) {
          stepWidth = 10;
        }
        // accelerate to completion
        stepWidth = stepWidth + stepWidth;
      }
    }, 10);
  },

  expandingAnimate() {
    let self = this,
        outer = this.$(),
        speed = this.getWithDefault('speed', 1000),
        colorQueue = this.get('color');

    if ('object' === typeof colorQueue) {
      (function updateFn() {
        let color = colorQueue.shift();
        colorQueue.push(color);
        self.expandItem.call(self, color);
        if ( ! self.get('isLoading')) {
          outer.empty();
        } else {
          window.setTimeout(updateFn, speed);
        }
      })();
    } else {
      this.expandItem.call(this, colorQueue, true);
    }
  },

  expandItem(color, cleanUp) {
    let self = this,
        inner = $('<span>').css({'background-color': color}),
        outer = this.$(),
        innerWidth = 0,
        outerWidth = outer.width(),
        stepWidth = Math.round(outerWidth / 50);

    outer.append(inner);

    let interval = window.setInterval(function() {
      let step = (innerWidth = innerWidth + stepWidth);
      if (innerWidth > outerWidth) {
        window.clearInterval(interval);
        if (cleanUp) {
          outer.empty();
        }
      }
      inner.css({
        'margin-left': '-' + step / 2 + 'px',
        'width': step
      });
    }, 10);
  },

  didInsertElement() {
    this.$().html('<span>');

    var color = this.get('color');
    if (color) {
      this.$('span').css('background-color', color);
    }
  }
});
<commit_msg>Fix for expanding animation on IE.<commit_after>import Ember from 'ember';

export default Ember.Component.extend({
  tagName: 'div',
  classNames: ['loading-slider'],
  classNameBindings: 'expanding',

  initialize: Ember.on('didReceiveAttrs', function() {
    this.set('isLoading', this.getAttr('isLoading'));
    this.set('duration', this.getAttr('duration'));
    this.set('expanding', this.getAttr('expanding'));
    this.set('speed', this.getAttr('speed'));
    this.set('color', this.getAttr('color'));

    this.manage();
  }),

  manage() {
    if (this.get('isLoading')) {
      if (this.get('expanding')) {
        this.expandingAnimate.call(this);
      } else {
        this.animate.call(this);
      }
    } else {
      this.set('isLoaded', true);
    }
  },

  animate() {
    this.set('isLoaded', false);
    let self = this,
        elapsedTime = 0,
        inner = $('<span>'),
        outer = this.$(),
        duration = this.getWithDefault('duration', 300),
        innerWidth = 0,
        outerWidth = this.$().width(),
        stepWidth = Math.round(outerWidth / 50),
        color = this.get('color');

    outer.append(inner);
    if (color) {
      inner.css('background-color', color);
    }

    let interval = window.setInterval(function() {
      elapsedTime = elapsedTime + 10;
      inner.width(innerWidth = innerWidth + stepWidth);

      // slow the animation if we used more than 75% the estimated duration
      // or 66% of the animation width
      if (elapsedTime > (duration * 0.75) || innerWidth > (outerWidth * 0.66)) {
        // don't stop the animation completely
        if (stepWidth > 1) {
          stepWidth = stepWidth * 0.97;
        }
      }

      if (innerWidth > outerWidth) {
        Ember.run.later(function() {
          outer.empty();
          window.clearInterval(interval);
        }, 50);
      }

      // the activity has finished
      if (self.get('isLoaded')) {
        // start with a sizable pixel step
        if (stepWidth < 10) {
          stepWidth = 10;
        }
        // accelerate to completion
        stepWidth = stepWidth + stepWidth;
      }
    }, 10);
  },

  expandingAnimate() {
    let self = this,
        outer = this.$(),
        speed = this.getWithDefault('speed', 1000),
        colorQueue = this.get('color');

    if ('object' === typeof colorQueue) {
      (function updateFn() {
        let color = colorQueue.shift();
        colorQueue.push(color);
        self.expandItem.call(self, color);
        if ( ! self.get('isLoading')) {
          outer.empty();
        } else {
          window.setTimeout(updateFn, speed);
        }
      })();
    } else {
      this.expandItem.call(this, colorQueue, true);
    }
  },

  expandItem(color, cleanUp) {
    let self = this,
        inner = $('<span>').css({'background-color': color}),
        outer = this.$(),
        innerWidth = 0,
        outerWidth = outer.width(),
        stepWidth = Math.round(outerWidth / 50);
    let ua = window.navigator.userAgent;
    let ie10 = ua.indexOf("MSIE "),
        ie11 = ua.indexOf('Trident/'),
        ieEdge = ua.indexOf('Edge/');

    outer.append(inner);

    let interval = window.setInterval(function() {
      let step = (innerWidth = innerWidth + stepWidth);
      if (innerWidth > outerWidth) {
        window.clearInterval(interval);
        if (cleanUp) {
          outer.empty();
        }
      }
      if (ie10 > 0 || ie11 > 0 || ieEdge > 0) {
        inner.css({
          'margin': '0 auto',
          'width': step
        });
      } else {
        inner.css({
          'margin-left': '-' + step / 2 + 'px',
          'width': step
        });
      }
    }, 10);
  },

  didInsertElement() {
    this.$().html('<span>');

    var color = this.get('color');
    if (color) {
      this.$('span').css('background-color', color);
    }
  }
});
<|endoftext|>


<commit_before>/*
 * Copyright 2014, Gregg Tavares.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Gregg Tavares. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

"use strict";

define([], function() {

  /**
   * This is similar to node's EventEmitter.
   * The major difference is calling `addEventListner`
   * or `removeEventListener` with `null` or `undefined`
   * will remove all listeners for that event.
   */
  var EventEmitter = function() {
    var events = {};
    var maxListeners = 10;

    var setMaxListeners = function(max) {
      maxListeners = max;
    };

    var addEventListener = function(name, handler) {
      if (!handler) {
        delete events[name];
        return;
      }

      var handlers = events[name];
      if (!handlers) {
        handlers = [];
        events[name] = handlers;
      }
      handlers.push(handler);
      if (handlers.length > maxListeners) {
        console.warn("More than " + maxListeners + " added to event " + name);
      }
    };

    var removeEventListener = function(name, handler) {
      if (!handler) {
        delete events[name];
        return;
      }

      var handlers = events[name];
      if (handlers) {
        var ndx = handlers.indexOf(handler);
        if (ndx >= 0) {
          handlers.splice(ndx, 1);
        }
      }
    };

    var removeAllEventListeners = function() {
      events = {};
    };

    var emit = function(name, ...args) {
      var handlers = events[name];
      if (handlers) {
        handlers.forEach(function(handler) {
          handler.apply(this, ...args);
        });
      }
    };

    var listeners = function(name) {
      return events[name];
    };

    this.on = addEventListener;
    this.addEventListener = addEventListener;
    this.removeEventListener = removeEventListener;
    this.removeAllEventListeners = removeAllEventListeners;
    this.addListener = addEventListener;
    this.removeListener = removeEventListener;
    this.removeAllListeners = removeAllEventListeners;
    this.emit = emit;
    this.listeners = listeners;
    this.setMaxListeners = setMaxListeners;
  };

  return EventEmitter;
});

<commit_msg>fix eventemitter<commit_after>/*
 * Copyright 2014, Gregg Tavares.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Gregg Tavares. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

"use strict";

define([], function() {

  /**
   * This is similar to node's EventEmitter.
   * The major difference is calling `addEventListner`
   * or `removeEventListener` with `null` or `undefined`
   * will remove all listeners for that event.
   */
  var EventEmitter = function() {
    var events = {};
    var maxListeners = 10;

    var setMaxListeners = function(max) {
      maxListeners = max;
    };

    var addEventListener = function(name, handler) {
      if (!handler) {
        delete events[name];
        return;
      }

      var handlers = events[name];
      if (!handlers) {
        handlers = [];
        events[name] = handlers;
      }
      handlers.push(handler);
      if (handlers.length > maxListeners) {
        console.warn("More than " + maxListeners + " added to event " + name);
      }
    };

    var removeEventListener = function(name, handler) {
      if (!handler) {
        delete events[name];
        return;
      }

      var handlers = events[name];
      if (handlers) {
        var ndx = handlers.indexOf(handler);
        if (ndx >= 0) {
          handlers.splice(ndx, 1);
        }
      }
    };

    var removeAllEventListeners = function() {
      events = {};
    };

    var emit = function(name, ...args) {
      var handlers = events[name];
      if (handlers) {
        handlers.forEach(function(handler) {
          handler(...args);
        });
      }
    };

    var listeners = function(name) {
      return events[name];
    };

    this.on = addEventListener;
    this.addEventListener = addEventListener;
    this.removeEventListener = removeEventListener;
    this.removeAllEventListeners = removeAllEventListeners;
    this.addListener = addEventListener;
    this.removeListener = removeEventListener;
    this.removeAllListeners = removeAllEventListeners;
    this.emit = emit;
    this.listeners = listeners;
    this.setMaxListeners = setMaxListeners;
  };

  return EventEmitter;
});

<|endoftext|>


<commit_before>var twolfson_style = require('../');

describe('twolfson-style', function () {
  before(function () {

  });

  it('', function () {

  });
});
<commit_msg>Started on test<commit_after>var assert = require('assert');
var twolfsonStyle = require('../');

describe('twolfson-style', function () {
  it('exports a function', function () {
    assert.strictEqual(typeof twolfsonStyle, 'function');
  });
});
<|endoftext|>


<commit_before>describe('TypeaheadView', function() {
  var fixture = '<input class="tt-test">',
      mockDatasets = [];

  ['dataset1', 'dataset2', 'dataset3'].forEach(function(datasetName) {
    mockDatasets.push({
      name: datasetName,
      limit: 4,
      template: '',
      engine: Hogan,
      getSuggestions: jasmine.createSpy()
        .andCallFake(function(q, cb) { cb([]); })
    });
  });

  beforeEach(function() {
    var $fixtures, $input;

    setFixtures(fixture);

    $fixtures = $('#jasmine-fixtures');
    $input = $fixtures.find('.tt-test');

    this.typeaheadView = new TypeaheadView({
      input: $input,
      datasets: mockDatasets
    });

    this.inputView = this.typeaheadView.inputView;
    this.dropdownView = this.typeaheadView.dropdownView;

    // spy on all inputView and dropdownView public methods
    [this.inputView, this.dropdownView].forEach(spyOnPublicMethods);
  });

  // handlers triggered by dropdownView events
  // -----------------------------------------

  describe('when dropdownView triggers select', function() {
    beforeEach(function() {
      this.dropdownView.trigger('select', { value: 'i am selected' });
    });

    it('should update input value', function() {
      expect(this.inputView.setInputValue)
      .toHaveBeenCalledWith('i am selected');
    });

    it('should focus input', function() {
      expect(this.inputView.focus).toHaveBeenCalled();
    });

    it('should hide dropdown', function() {
      expect(this.dropdownView.hide).toHaveBeenCalled();
    });
  });

  describe('when dropdownView triggers cursorOn', function() {
    beforeEach(function() {
      this.dropdownView.trigger('cursorOn', { value: 'i am hint' });
    });

    it('should clear hint', function() {
      expect(this.inputView.setHintValue).toHaveBeenCalledWith('');
    });

    it('should set input value to suggestion value', function() {
      expect(this.inputView.setInputValue)
      .toHaveBeenCalledWith('i am hint', true);
    });
  });

  describe('when dropdownView triggers cursorOff', function() {
    it('should reset input value to user query', function() {
      this.inputView.getQuery.andReturn('san   ');
      this.dropdownView.trigger('cursorOff');

      expect(this.inputView.setInputValue).toHaveBeenCalledWith('san   ');
    });

    _updateHintSpecHelper('dropdownView', 'cursorOff');
  });

  describe('when dropdownView triggers suggestionsRender', function() {
    _updateHintSpecHelper('dropdownView', 'suggestionsRender');
  });

  describe('when dropdownView triggers hide', function() {
    beforeEach(function() {
      this.dropdownView.trigger('hide');
    });

    it('should clear hint', function() {
      expect(this.inputView.setHintValue).toHaveBeenCalledWith('');
    });
  });

  // handlers triggered by inputView events
  // --------------------------------------

  describe('when inputView triggers blur', function() {
    beforeEach(function() {
      this.inputView.getQuery.andReturn('reset');

      this.inputView.trigger('blur');
    });

    it('should hide dropdown unless mouse is over it', function() {
      expect(this.dropdownView.hideUnlessMouseIsOverDropdown)
      .toHaveBeenCalled();
    });

    it('should reset input value to user query', function() {
      expect(this.inputView.setInputValue).toHaveBeenCalledWith('reset');
    });
  });

  describe('when inputView triggers enter', function() {
    beforeEach(function() {
      this.spy = jasmine.createSpy();

      this.dropdownView.getSuggestionUnderCursor
      .andReturn({ value: 'i am selected' });

      this.inputView.trigger('enter', { preventDefault: this.spy });
    });

    it('should update input value', function() {
      expect(this.inputView.setInputValue)
      .toHaveBeenCalledWith('i am selected');
    });

    it('should prevent form submissions', function() {
      expect(this.spy).toHaveBeenCalled();
    });

    it('should hide dropdown', function() {
      expect(this.dropdownView.hide).toHaveBeenCalled();
    });
  });

  describe('when inputView triggers whitespaceChange', function() {
    _updateHintSpecHelper('inputView', 'whitespaceChange');

    it('should show the dropdown menu', function() {
      this.inputView.trigger('whitespaceChange');
      expect(this.dropdownView.show).toHaveBeenCalled();
    });

    describe('if language direction has changed', function() {
      beforeEach(function() {
        this.typeaheadView.$node
        .removeClass('tt-ltr tt-rtl')
        .addClass('tt-ltr');

        this.inputView.getLanguageDirection.andReturn('rtl');
        this.inputView.trigger('whitespaceChange');
      });

      it('should update langauge class name', function() {
        expect(this.typeaheadView.$node).toHaveClass('tt-rtl');
        expect(this.typeaheadView.$node).not.toHaveClass('tt-ltr');
      });
    });
  });

  describe('when inputView triggers queryChange', function() {
    it('should show the dropdown menu', function() {
      this.inputView.trigger('queryChange');
      expect(this.dropdownView.show).toHaveBeenCalled();
    });

    it('should clear hint', function() {
      this.inputView.trigger('queryChange');
      expect(this.inputView.setHintValue).toHaveBeenCalledWith('');
    });

    it('should clear suggestions', function() {
      this.inputView.trigger('queryChange');
      expect(this.dropdownView.clearSuggestions).toHaveBeenCalled();
    });

    it('should call dropdownView.renderSuggestions for each dataset',
    function() {
      this.inputView.trigger('queryChange');
      expect(this.dropdownView.renderSuggestions.callCount).toBe(3);
    });

    describe('if language direction has changed', function() {
      beforeEach(function() {
        this.typeaheadView.$node
        .removeClass('tt-ltr tt-rtl')
        .addClass('tt-ltr');

        this.inputView.getLanguageDirection.andReturn('rtl');
        this.inputView.trigger('queryChange');
      });

      it('should update langauge class name', function() {
        expect(this.typeaheadView.$node).toHaveClass('tt-rtl');
        expect(this.typeaheadView.$node).not.toHaveClass('tt-ltr');
      });
    });
  });

  describe('when inputView triggers focus', function() {
    beforeEach(function() {
      this.inputView.trigger('focus');
    });

    it('should show the dropdown menu', function() {
      expect(this.dropdownView.show).toHaveBeenCalled();
    });
  });

  describe('when inputView triggers esc', function() {
    beforeEach(function() {
      this.inputView.getQuery.andReturn('reset');

      this.inputView.trigger('esc');
    });

    it('should hide dropdown', function() {
      expect(this.dropdownView.hide).toHaveBeenCalled();
    });

    it('should reset input value to user query', function() {
      expect(this.inputView.setInputValue).toHaveBeenCalledWith('reset');
    });
  });

  describe('when input View triggers up', function() {

    describe('if modifier key was pressed', function() {
      beforeEach(function() {
        this.$e = $.extend($.Event('keydown'), { keyCode: 38, shiftKey: true });
        spyOn(this.$e, 'preventDefault');

        this.inputView.trigger('up', this.$e);
      });

      it('should show the dropdown menu', function() {
        expect(this.dropdownView.show).toHaveBeenCalled();
      });

      it('should not prevent default browser behavior', function() {
        expect(this.$e.preventDefault).not.toHaveBeenCalled();
      });

      it('should not move cursor up', function() {
        expect(this.dropdownView.moveCursorUp).not.toHaveBeenCalled();
      });
    });

    describe('if modifier key was not pressed', function() {
      beforeEach(function() {
        this.$e = $.extend($.Event('keydown'), { keyCode: 38 });
        spyOn(this.$e, 'preventDefault');

        this.inputView.trigger('up', this.$e);
      });

      it('should show the dropdown menu', function() {
        expect(this.dropdownView.show).toHaveBeenCalled();
      });

      it('should prevent default browser behavior', function() {
        expect(this.$e.preventDefault).toHaveBeenCalled();
      });

      it('should move cursor up', function() {
        expect(this.dropdownView.moveCursorUp).toHaveBeenCalled();
      });
    });
  });

  describe('when input View triggers down', function() {

    describe('if modifier key was pressed', function() {
      beforeEach(function() {
        this.$e = $.extend($.Event('keydown'), { keyCode: 40, shiftKey: true });
        spyOn(this.$e, 'preventDefault');

        this.inputView.trigger('down', this.$e);
      });

      it('should show the dropdown menu', function() {
        expect(this.dropdownView.show).toHaveBeenCalled();
      });

      it('should not prevent default browser behavior', function() {
        expect(this.$e.preventDefault).not.toHaveBeenCalled();
      });

      it('should not move cursor down', function() {
        expect(this.dropdownView.moveCursorDown).not.toHaveBeenCalled();
      });
    });

    describe('if modifier key was not pressed', function() {
      beforeEach(function() {
        this.$e = $.extend($.Event('keydown'), { keyCode: 40 });
        spyOn(this.$e, 'preventDefault');

        this.inputView.trigger('down', this.$e);
      });

      it('should show the dropdown menu', function() {
        expect(this.dropdownView.show).toHaveBeenCalled();
      });

      it('should prevent default browser behavior', function() {
        expect(this.$e.preventDefault).toHaveBeenCalled();
      });

      it('should move cursor down', function() {
        expect(this.dropdownView.moveCursorDown).toHaveBeenCalled();
      });
    });
  });

  describe('when inputView triggers tab', function() {
    beforeEach(function() {
      this.$e = $.extend($.Event('keydown'), { keyCode: 9 });
      spyOn(this.$e, 'preventDefault');
    });

    describe('if hint is empty string', function() {
      beforeEach(function() {
        this.inputView.getHintValue.andReturn('');

        this.inputView.trigger('tab', this.$e);
      });

      it('should not update input value', function() {
        expect(this.inputView.setInputValue).not.toHaveBeenCalled();
      });

      it('should not prevent default browser behavior', function() {
        expect(this.$e.preventDefault).not.toHaveBeenCalled();
      });
    });

    describe('if hint differs from query', function() {
      beforeEach(function() {
        this.inputView.getQuery.andReturn('app');
        this.inputView.getHintValue.andReturn('apple');

        this.inputView.trigger('tab', this.$e);
      });

      it('should update input value', function() {
        expect(this.inputView.setInputValue).toHaveBeenCalled();
      });

      it('should prevent default browser behavior', function() {
        expect(this.$e.preventDefault).toHaveBeenCalled();
      });
    });
  });

  describe('when inputView triggers left', function() {
    beforeEach(function() {
      this.inputView.getQuery.andReturn('app');
      this.inputView.getHintValue.andReturn('apple');
      this.inputView.isCursorAtEnd.andReturn(true);
      this.inputView.getLanguageDirection.andReturn('ltr');
    });

    describe('if being viewed in ltr language', function() {
      beforeEach(function() {
        this.inputView.getLanguageDirection.andReturn('ltr');

        this.inputView.trigger('left');
      });

      it('should not update input value', function() {
        expect(this.inputView.setInputValue).not.toHaveBeenCalled();
      });
    });

    describe('if being viewed in rtl language', function() {
      beforeEach(function() {
        this.inputView.getLanguageDirection.andReturn('rtl');

        this.inputView.trigger('left');
      });

      it('should update value of input', function() {
        expect(this.inputView.setInputValue).toHaveBeenCalled();
      });
    });

    describe('if cursor is not at then end of the query', function() {
      beforeEach(function() {
        this.inputView.isCursorAtEnd.andReturn(false);

        this.inputView.trigger('left');
      });

      it('should not update input value', function() {
        expect(this.inputView.setInputValue).not.toHaveBeenCalled();
      });
    });
  });

  describe('when inputView triggers right', function() {
    beforeEach(function() {
      this.inputView.getQuery.andReturn('app');
      this.inputView.getHintValue.andReturn('apple');
      this.inputView.isCursorAtEnd.andReturn(true);
      this.inputView.getLanguageDirection.andReturn('ltr');
    });

    describe('if being viewed in ltr language', function() {
      beforeEach(function() {
        this.inputView.getLanguageDirection.andReturn('ltr');

        this.inputView.trigger('right');
      });

      it('should update input value', function() {
        expect(this.inputView.setInputValue).toHaveBeenCalled();
      });
    });

    describe('if being viewed in rtl language', function() {
      beforeEach(function() {
        this.inputView.getLanguageDirection.andReturn('rtl');

        this.inputView.trigger('right');
      });

      it('should not update input value', function() {
        expect(this.inputView.setInputValue).not.toHaveBeenCalled();
      });
    });

    describe('if cursor is not at then end of the query', function() {
      beforeEach(function() {
        this.inputView.isCursorAtEnd.andReturn(false);

        this.inputView.trigger('right');
      });

      it('should not update input value', function() {
        expect(this.inputView.setInputValue).not.toHaveBeenCalled();
      });
    });
  });

  // spec helpers
  // ------------

  function _updateHintSpecHelper(view, eventType) {
    describe('if dropdown menu is closed', function() {
      it('should not show hint', function() {
        this.dropdownView.isOpen.andReturn(false);
        this.inputView.getInputValue.andReturn('san   ');
        this.dropdownView.getFirstSuggestion
        .andReturn({ value: 'desert sand' });

        this[view].trigger(eventType);

        expect(this.inputView.setHintValue).not.toHaveBeenCalled();
      });
    });

    describe('if top suggestion\'s value begins with query', function() {
      it('should show hint', function() {
        this.dropdownView.isOpen.andReturn(true);
        this.inputView.getInputValue.andReturn('san   ');
        this.dropdownView.getFirstSuggestion
        .andReturn({ value: 'san francisco' });

        this[view].trigger(eventType);

        expect(this.inputView.setHintValue)
        .toHaveBeenCalledWith('san   francisco');
      });
    });

    describe('if top suggestion\'s value does not begin with query',
    function() {
      it('should not show hint', function() {
        this.dropdownView.isOpen.andReturn(true);
        this.inputView.getInputValue.andReturn('san   ');
        this.dropdownView.getFirstSuggestion
        .andReturn({ value: 'desert sand' });

        this[view].trigger(eventType);

        expect(this.inputView.setHintValue).toHaveBeenCalledWith('san   ');
      });
    });
  }

  // helper functions
  // ----------------

  function spyOnPublicMethods(view) {
    var isEventMethod, isPublicMethod;

    for (var key in view) {
      if (view.hasOwnProperty(key)) {
        isEventMethod = ~['on', 'off', 'trigger'].indexOf(key);
        isPublicMethod = typeof view[key] == 'function' && !/^_/.test(key);

        if (view.hasOwnProperty(key) && isPublicMethod && !isEventMethod) {
          spyOn(view, key);
        }
      }
    }
  }
});
<commit_msg>Fix typo.<commit_after>describe('TypeaheadView', function() {
  var fixture = '<input class="tt-test">',
      mockDatasets = [];

  ['dataset1', 'dataset2', 'dataset3'].forEach(function(datasetName) {
    mockDatasets.push({
      name: datasetName,
      limit: 4,
      template: '',
      engine: Hogan,
      getSuggestions: jasmine.createSpy()
        .andCallFake(function(q, cb) { cb([]); })
    });
  });

  beforeEach(function() {
    var $fixtures, $input;

    setFixtures(fixture);

    $fixtures = $('#jasmine-fixtures');
    $input = $fixtures.find('.tt-test');

    this.typeaheadView = new TypeaheadView({
      input: $input,
      datasets: mockDatasets
    });

    this.inputView = this.typeaheadView.inputView;
    this.dropdownView = this.typeaheadView.dropdownView;

    // spy on all inputView and dropdownView public methods
    [this.inputView, this.dropdownView].forEach(spyOnPublicMethods);
  });

  // handlers triggered by dropdownView events
  // -----------------------------------------

  describe('when dropdownView triggers select', function() {
    beforeEach(function() {
      this.dropdownView.trigger('select', { value: 'i am selected' });
    });

    it('should update input value', function() {
      expect(this.inputView.setInputValue)
      .toHaveBeenCalledWith('i am selected');
    });

    it('should focus input', function() {
      expect(this.inputView.focus).toHaveBeenCalled();
    });

    it('should hide dropdown', function() {
      expect(this.dropdownView.hide).toHaveBeenCalled();
    });
  });

  describe('when dropdownView triggers cursorOn', function() {
    beforeEach(function() {
      this.dropdownView.trigger('cursorOn', { value: 'i am hint' });
    });

    it('should clear hint', function() {
      expect(this.inputView.setHintValue).toHaveBeenCalledWith('');
    });

    it('should set input value to suggestion value', function() {
      expect(this.inputView.setInputValue)
      .toHaveBeenCalledWith('i am hint', true);
    });
  });

  describe('when dropdownView triggers cursorOff', function() {
    it('should reset input value to user query', function() {
      this.inputView.getQuery.andReturn('san   ');
      this.dropdownView.trigger('cursorOff');

      expect(this.inputView.setInputValue).toHaveBeenCalledWith('san   ');
    });

    _updateHintSpecHelper('dropdownView', 'cursorOff');
  });

  describe('when dropdownView triggers suggestionsRender', function() {
    _updateHintSpecHelper('dropdownView', 'suggestionsRender');
  });

  describe('when dropdownView triggers hide', function() {
    beforeEach(function() {
      this.dropdownView.trigger('hide');
    });

    it('should clear hint', function() {
      expect(this.inputView.setHintValue).toHaveBeenCalledWith('');
    });
  });

  // handlers triggered by inputView events
  // --------------------------------------

  describe('when inputView triggers blur', function() {
    beforeEach(function() {
      this.inputView.getQuery.andReturn('reset');

      this.inputView.trigger('blur');
    });

    it('should hide dropdown unless mouse is over it', function() {
      expect(this.dropdownView.hideUnlessMouseIsOverDropdown)
      .toHaveBeenCalled();
    });

    it('should reset input value to user query', function() {
      expect(this.inputView.setInputValue).toHaveBeenCalledWith('reset');
    });
  });

  describe('when inputView triggers enter', function() {
    beforeEach(function() {
      this.spy = jasmine.createSpy();

      this.dropdownView.getSuggestionUnderCursor
      .andReturn({ value: 'i am selected' });

      this.inputView.trigger('enter', { preventDefault: this.spy });
    });

    it('should update input value', function() {
      expect(this.inputView.setInputValue)
      .toHaveBeenCalledWith('i am selected');
    });

    it('should prevent form submissions', function() {
      expect(this.spy).toHaveBeenCalled();
    });

    it('should hide dropdown', function() {
      expect(this.dropdownView.hide).toHaveBeenCalled();
    });
  });

  describe('when inputView triggers whitespaceChange', function() {
    _updateHintSpecHelper('inputView', 'whitespaceChange');

    it('should show the dropdown menu', function() {
      this.inputView.trigger('whitespaceChange');
      expect(this.dropdownView.show).toHaveBeenCalled();
    });

    describe('if language direction has changed', function() {
      beforeEach(function() {
        this.typeaheadView.$node
        .removeClass('tt-ltr tt-rtl')
        .addClass('tt-ltr');

        this.inputView.getLanguageDirection.andReturn('rtl');
        this.inputView.trigger('whitespaceChange');
      });

      it('should update langauge class name', function() {
        expect(this.typeaheadView.$node).toHaveClass('tt-rtl');
        expect(this.typeaheadView.$node).not.toHaveClass('tt-ltr');
      });
    });
  });

  describe('when inputView triggers queryChange', function() {
    it('should show the dropdown menu', function() {
      this.inputView.trigger('queryChange');
      expect(this.dropdownView.show).toHaveBeenCalled();
    });

    it('should clear hint', function() {
      this.inputView.trigger('queryChange');
      expect(this.inputView.setHintValue).toHaveBeenCalledWith('');
    });

    it('should clear suggestions', function() {
      this.inputView.trigger('queryChange');
      expect(this.dropdownView.clearSuggestions).toHaveBeenCalled();
    });

    it('should call dropdownView.renderSuggestions for each dataset',
    function() {
      this.inputView.trigger('queryChange');
      expect(this.dropdownView.renderSuggestions.callCount).toBe(3);
    });

    describe('if language direction has changed', function() {
      beforeEach(function() {
        this.typeaheadView.$node
        .removeClass('tt-ltr tt-rtl')
        .addClass('tt-ltr');

        this.inputView.getLanguageDirection.andReturn('rtl');
        this.inputView.trigger('queryChange');
      });

      it('should update langauge class name', function() {
        expect(this.typeaheadView.$node).toHaveClass('tt-rtl');
        expect(this.typeaheadView.$node).not.toHaveClass('tt-ltr');
      });
    });
  });

  describe('when inputView triggers focus', function() {
    beforeEach(function() {
      this.inputView.trigger('focus');
    });

    it('should show the dropdown menu', function() {
      expect(this.dropdownView.show).toHaveBeenCalled();
    });
  });

  describe('when inputView triggers esc', function() {
    beforeEach(function() {
      this.inputView.getQuery.andReturn('reset');

      this.inputView.trigger('esc');
    });

    it('should hide dropdown', function() {
      expect(this.dropdownView.hide).toHaveBeenCalled();
    });

    it('should reset input value to user query', function() {
      expect(this.inputView.setInputValue).toHaveBeenCalledWith('reset');
    });
  });

  describe('when inputView triggers up', function() {

    describe('if modifier key was pressed', function() {
      beforeEach(function() {
        this.$e = $.extend($.Event('keydown'), { keyCode: 38, shiftKey: true });
        spyOn(this.$e, 'preventDefault');

        this.inputView.trigger('up', this.$e);
      });

      it('should show the dropdown menu', function() {
        expect(this.dropdownView.show).toHaveBeenCalled();
      });

      it('should not prevent default browser behavior', function() {
        expect(this.$e.preventDefault).not.toHaveBeenCalled();
      });

      it('should not move cursor up', function() {
        expect(this.dropdownView.moveCursorUp).not.toHaveBeenCalled();
      });
    });

    describe('if modifier key was not pressed', function() {
      beforeEach(function() {
        this.$e = $.extend($.Event('keydown'), { keyCode: 38 });
        spyOn(this.$e, 'preventDefault');

        this.inputView.trigger('up', this.$e);
      });

      it('should show the dropdown menu', function() {
        expect(this.dropdownView.show).toHaveBeenCalled();
      });

      it('should prevent default browser behavior', function() {
        expect(this.$e.preventDefault).toHaveBeenCalled();
      });

      it('should move cursor up', function() {
        expect(this.dropdownView.moveCursorUp).toHaveBeenCalled();
      });
    });
  });

  describe('when inputView triggers down', function() {

    describe('if modifier key was pressed', function() {
      beforeEach(function() {
        this.$e = $.extend($.Event('keydown'), { keyCode: 40, shiftKey: true });
        spyOn(this.$e, 'preventDefault');

        this.inputView.trigger('down', this.$e);
      });

      it('should show the dropdown menu', function() {
        expect(this.dropdownView.show).toHaveBeenCalled();
      });

      it('should not prevent default browser behavior', function() {
        expect(this.$e.preventDefault).not.toHaveBeenCalled();
      });

      it('should not move cursor down', function() {
        expect(this.dropdownView.moveCursorDown).not.toHaveBeenCalled();
      });
    });

    describe('if modifier key was not pressed', function() {
      beforeEach(function() {
        this.$e = $.extend($.Event('keydown'), { keyCode: 40 });
        spyOn(this.$e, 'preventDefault');

        this.inputView.trigger('down', this.$e);
      });

      it('should show the dropdown menu', function() {
        expect(this.dropdownView.show).toHaveBeenCalled();
      });

      it('should prevent default browser behavior', function() {
        expect(this.$e.preventDefault).toHaveBeenCalled();
      });

      it('should move cursor down', function() {
        expect(this.dropdownView.moveCursorDown).toHaveBeenCalled();
      });
    });
  });

  describe('when inputView triggers tab', function() {
    beforeEach(function() {
      this.$e = $.extend($.Event('keydown'), { keyCode: 9 });
      spyOn(this.$e, 'preventDefault');
    });

    describe('if hint is empty string', function() {
      beforeEach(function() {
        this.inputView.getHintValue.andReturn('');

        this.inputView.trigger('tab', this.$e);
      });

      it('should not update input value', function() {
        expect(this.inputView.setInputValue).not.toHaveBeenCalled();
      });

      it('should not prevent default browser behavior', function() {
        expect(this.$e.preventDefault).not.toHaveBeenCalled();
      });
    });

    describe('if hint differs from query', function() {
      beforeEach(function() {
        this.inputView.getQuery.andReturn('app');
        this.inputView.getHintValue.andReturn('apple');

        this.inputView.trigger('tab', this.$e);
      });

      it('should update input value', function() {
        expect(this.inputView.setInputValue).toHaveBeenCalled();
      });

      it('should prevent default browser behavior', function() {
        expect(this.$e.preventDefault).toHaveBeenCalled();
      });
    });
  });

  describe('when inputView triggers left', function() {
    beforeEach(function() {
      this.inputView.getQuery.andReturn('app');
      this.inputView.getHintValue.andReturn('apple');
      this.inputView.isCursorAtEnd.andReturn(true);
      this.inputView.getLanguageDirection.andReturn('ltr');
    });

    describe('if being viewed in ltr language', function() {
      beforeEach(function() {
        this.inputView.getLanguageDirection.andReturn('ltr');

        this.inputView.trigger('left');
      });

      it('should not update input value', function() {
        expect(this.inputView.setInputValue).not.toHaveBeenCalled();
      });
    });

    describe('if being viewed in rtl language', function() {
      beforeEach(function() {
        this.inputView.getLanguageDirection.andReturn('rtl');

        this.inputView.trigger('left');
      });

      it('should update value of input', function() {
        expect(this.inputView.setInputValue).toHaveBeenCalled();
      });
    });

    describe('if cursor is not at then end of the query', function() {
      beforeEach(function() {
        this.inputView.isCursorAtEnd.andReturn(false);

        this.inputView.trigger('left');
      });

      it('should not update input value', function() {
        expect(this.inputView.setInputValue).not.toHaveBeenCalled();
      });
    });
  });

  describe('when inputView triggers right', function() {
    beforeEach(function() {
      this.inputView.getQuery.andReturn('app');
      this.inputView.getHintValue.andReturn('apple');
      this.inputView.isCursorAtEnd.andReturn(true);
      this.inputView.getLanguageDirection.andReturn('ltr');
    });

    describe('if being viewed in ltr language', function() {
      beforeEach(function() {
        this.inputView.getLanguageDirection.andReturn('ltr');

        this.inputView.trigger('right');
      });

      it('should update input value', function() {
        expect(this.inputView.setInputValue).toHaveBeenCalled();
      });
    });

    describe('if being viewed in rtl language', function() {
      beforeEach(function() {
        this.inputView.getLanguageDirection.andReturn('rtl');

        this.inputView.trigger('right');
      });

      it('should not update input value', function() {
        expect(this.inputView.setInputValue).not.toHaveBeenCalled();
      });
    });

    describe('if cursor is not at then end of the query', function() {
      beforeEach(function() {
        this.inputView.isCursorAtEnd.andReturn(false);

        this.inputView.trigger('right');
      });

      it('should not update input value', function() {
        expect(this.inputView.setInputValue).not.toHaveBeenCalled();
      });
    });
  });

  // spec helpers
  // ------------

  function _updateHintSpecHelper(view, eventType) {
    describe('if dropdown menu is closed', function() {
      it('should not show hint', function() {
        this.dropdownView.isOpen.andReturn(false);
        this.inputView.getInputValue.andReturn('san   ');
        this.dropdownView.getFirstSuggestion
        .andReturn({ value: 'desert sand' });

        this[view].trigger(eventType);

        expect(this.inputView.setHintValue).not.toHaveBeenCalled();
      });
    });

    describe('if top suggestion\'s value begins with query', function() {
      it('should show hint', function() {
        this.dropdownView.isOpen.andReturn(true);
        this.inputView.getInputValue.andReturn('san   ');
        this.dropdownView.getFirstSuggestion
        .andReturn({ value: 'san francisco' });

        this[view].trigger(eventType);

        expect(this.inputView.setHintValue)
        .toHaveBeenCalledWith('san   francisco');
      });
    });

    describe('if top suggestion\'s value does not begin with query',
    function() {
      it('should not show hint', function() {
        this.dropdownView.isOpen.andReturn(true);
        this.inputView.getInputValue.andReturn('san   ');
        this.dropdownView.getFirstSuggestion
        .andReturn({ value: 'desert sand' });

        this[view].trigger(eventType);

        expect(this.inputView.setHintValue).toHaveBeenCalledWith('san   ');
      });
    });
  }

  // helper functions
  // ----------------

  function spyOnPublicMethods(view) {
    var isEventMethod, isPublicMethod;

    for (var key in view) {
      if (view.hasOwnProperty(key)) {
        isEventMethod = ~['on', 'off', 'trigger'].indexOf(key);
        isPublicMethod = typeof view[key] == 'function' && !/^_/.test(key);

        if (view.hasOwnProperty(key) && isPublicMethod && !isEventMethod) {
          spyOn(view, key);
        }
      }
    }
  }
});
<|endoftext|>


<commit_before>// Load in depdendencies
var assert = require('assert');
var url = require('url');
var FixedServer = require('fixed-server');
var nineTrack = require('nine-track');
var config = require('./config');

// Define our FakePinboard server
var fakePinboard = new FixedServer({port: config.fakePinboardUrl.port});
var pinboardNineTrack = nineTrack({
  url: 'https://api.pinboard.in',
  fixtureDir: __dirname + '/../test-files/pinboard-nine-track/',
  // Normalize/scrub authentication info
  scrubFn: function (info) {
    // Parse our URL
    var req = info.request;
    var urlObj = url.parse(req.url, true);

    // If there is a query object and we have auth info, normalize it
    if (urlObj.query && urlObj.query.auth_token) {
      urlObj.query.auth_token = '*:*';
      delete urlObj.search;

      // Save our updated URL
      req.url = url.format(urlObj);
    }
  }
});

// Add per-method proxies
fakePinboard.addFixture('GET 200 /v1/posts/update', {
  method: 'get',
  route: '/v1/posts/update',
  response: function fakePostsUpdate (localReq, localRes) {
    // Forward the request
    pinboardNineTrack.forwardRequest(localReq, function handleResponse (err, remoteRes, remoteBody) {
      // If there is an error, throw it
      if (err) {
        throw err;
      }

      // Otherwise, adjust the body
      var remoteJson = JSON.parse(remoteBody);
      if (remoteJson.update_time) {
        // Adjust ISO timestamp format (e.g. `2014-01-29T09:42:58Z`)
        remoteJson.update_time = remoteJson.update_time.replace(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/,
          '2015-02-01T00:00:00Z');
      }

      // Send back our response
      localRes.json(remoteJson);
    });
  }
});

fakePinboard.addFixture('GET 200 /v1/tags/get', {
  method: 'get',
  route: '/v1/tags/get',
  response: function fakeTagsGet (localReq, localRes) {
    // Forward the request
    pinboardNineTrack.forwardRequest(localReq, function handleResponse (err, remoteRes, remoteBody) {
      // If there is an error, throw it
      if (err) {
        throw err;
      }

      // Otherwise, adjust the body
      var remoteJson = JSON.parse(remoteBody);
      if (typeof remoteJson === 'object') {
        // Add in our expected tag
        remoteJson['test-tag'] = 1;
      }

      // Send back our response
      localRes.json(remoteJson);
    });
  }
});

// Add a method to proxy anything
fakePinboard.addFixture('ALL * *', {
  method: 'all',
  route: '*',
  response: pinboardNineTrack
});

// Add custom methods to start/stop `nine-track` series
// DEV: We keep key and fixtures together to prevent fragmentations. This should be all or nothing for a test case.
fakePinboard.runSeries = function (key, fixtures) {
  assert(key, '`fakePinboard.runSeries` requires `key` to run. Please provide it');
  assert(fixtures, '`fakePinboard.runSeries` requires `fixtures` to run. Please provide it');
  before(function startSeries () {
    pinboardNineTrack.startSeries(key);
  });
  after(function stopSeries () {
    pinboardNineTrack.stopSeries();
  });
  fakePinboard.run(fixtures);
};

// Expose our fake server
module.exports = fakePinboard;
<commit_msg>Added fixture for secret handling<commit_after>// Load in depdendencies
var assert = require('assert');
var url = require('url');
var FixedServer = require('fixed-server');
var nineTrack = require('nine-track');
var xtend = require('xtend');
var config = require('./config');

// Define our FakePinboard server
var fakePinboard = new FixedServer({port: config.fakePinboardUrl.port});
var pinboardNineTrackOptions = {
  url: 'https://api.pinboard.in',
  fixtureDir: __dirname + '/../test-files/pinboard-nine-track/',
  // Normalize/scrub authentication info
  scrubFn: function (info) {
    // Parse our URL
    var req = info.request;
    var urlObj = url.parse(req.url, true);

    // If there is a query object and we have auth info, normalize it
    if (urlObj.query && urlObj.query.auth_token) {
      urlObj.query.auth_token = '*:*';
      delete urlObj.search;

      // Save our updated URL
      req.url = url.format(urlObj);
    }
  }
};
var pinboardNineTrack = nineTrack(pinboardNineTrackOptions);

// Add per-method proxies
fakePinboard.addFixture('GET 200 /v1/posts/update', {
  method: 'get',
  route: '/v1/posts/update',
  response: function fakePostsUpdate (localReq, localRes) {
    // Forward the request
    pinboardNineTrack.forwardRequest(localReq, function handleResponse (err, remoteRes, remoteBody) {
      // If there is an error, throw it
      if (err) {
        throw err;
      }

      // Otherwise, adjust the body
      var remoteJson = JSON.parse(remoteBody);
      if (remoteJson.update_time) {
        // Adjust ISO timestamp format (e.g. `2014-01-29T09:42:58Z`)
        remoteJson.update_time = remoteJson.update_time.replace(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/,
          '2015-02-01T00:00:00Z');
      }

      // Send back our response
      localRes.json(remoteJson);
    });
  }
});

fakePinboard.addFixture('GET 200 /v1/tags/get', {
  method: 'get',
  route: '/v1/tags/get',
  response: function fakeTagsGet (localReq, localRes) {
    // Forward the request
    pinboardNineTrack.forwardRequest(localReq, function handleResponse (err, remoteRes, remoteBody) {
      // If there is an error, throw it
      if (err) {
        throw err;
      }

      // Otherwise, adjust the body
      var remoteJson = JSON.parse(remoteBody);
      if (typeof remoteJson === 'object') {
        // Add in our expected tag
        remoteJson['test-tag'] = 1;
      }

      // Send back our response
      localRes.json(remoteJson);
    });
  }
});

fakePinboard.addFixture('GET /v1/user/secret', {
  method: 'get',
  route: '/v1/user/secret',
  response: nineTrack(xtend({}, pinboardNineTrackOptions, {
    scrubFn: function (info) {
      // Normalize/scrub authentication info with original fn
      pinboardNineTrackOptions.scrubFn.call(this, info);

      // If we have a response, scrub it
      if (info.response) {
        console.log(info.response);
      }
    }
  }))
});

// Add a method to proxy anything
fakePinboard.addFixture('ALL * *', {
  method: 'all',
  route: '*',
  response: pinboardNineTrack
});

// Add custom methods to start/stop `nine-track` series
// DEV: We keep key and fixtures together to prevent fragmentations. This should be all or nothing for a test case.
fakePinboard.runSeries = function (key, fixtures) {
  assert(key, '`fakePinboard.runSeries` requires `key` to run. Please provide it');
  assert(fixtures, '`fakePinboard.runSeries` requires `fixtures` to run. Please provide it');
  before(function startSeries () {
    pinboardNineTrack.startSeries(key);
  });
  after(function stopSeries () {
    pinboardNineTrack.stopSeries();
  });
  fakePinboard.run(fixtures);
};

// Expose our fake server
module.exports = fakePinboard;
<|endoftext|>


<commit_before>import { expect } from 'chai';
import { MsgpackSerializer } from './../src/serializers/MsgpackSerializer';
import { JsonSerializer } from './../src/serializers/JsonSerializer';
import { Wampy } from './../src/wampy';
import { w3cwebsocket } from 'websocket';

describe('Wampy.js with Crossbar', function () {
    this.timeout(10000);

    it('Works with Json serializer', function (done) {

        const server = new Wampy('ws://localhost:8888/test', {
            realm: 'realm1',
            serializer: new JsonSerializer(),
            ws: w3cwebsocket,
            onConnect: () => {
                server.register('sayhello', () => {
                    return { argsList: 'hello' };
                });
            }
        });

        const client = new Wampy('ws://localhost:8888/test', {
            realm: 'realm1',
            serializer: new JsonSerializer(),
            ws: w3cwebsocket,
            onConnect: () => {
                client.call('sayhello', [], result => {
                    expect(result.argsList.shift()).to.equal('hello');
                    done();
                });
            }
        });
    });

    it('works with Msgpack serialization', function (done) {

        const server = new Wampy('ws://localhost:8888/test', {
            realm: 'realm1',
            serializer: new MsgpackSerializer(),
            ws: w3cwebsocket,
            onConnect: () => {
                server.register('sayhello', () => {
                    return { argsList: 'hello' };
                });
            }
        });

        const client = new Wampy('ws://localhost:8888/test', {
            realm: 'realm1',
            serializer: new MsgpackSerializer(),
            ws: w3cwebsocket,
            onConnect: () => {
                client.call('sayhello', [], result => {
                    expect(result.argsList.shift()).to.equal('hello');
                    done();
                });
            }
        });

    });
});
<commit_msg>Refactored crossbar tests<commit_after>import { expect } from 'chai';
import { MsgpackSerializer } from './../src/serializers/MsgpackSerializer';
import { JsonSerializer } from './../src/serializers/JsonSerializer';
import { Wampy } from './../src/wampy';
import { w3cwebsocket } from 'websocket';

describe('Wampy.js with Crossbar', function () {
    this.timeout(10000);

    it('Works with Json serializer', function (done) {

        const server = new Wampy('ws://localhost:8888/test', {
            realm: 'realm1',
            serializer: new JsonSerializer(),
            ws: w3cwebsocket,
            onConnect: () => {
                server.register('sayhello', {
                    rpc: () => {
                        return { argsList: 'hello' };
                    },
                    onSuccess: () => {
                        const client = new Wampy('ws://localhost:8888/test', {
                            realm: 'realm1',
                            serializer: new JsonSerializer(),
                            ws: w3cwebsocket,
                            onConnect: () => {
                                client.call('sayhello', [], result => {
                                    expect(result.argsList.shift()).to.equal('hello');
                                    done();
                                });
                            }
                        });
                    }
                });
            }
        });

    });

    it('works with Msgpack serialization', function (done) {

        const server = new Wampy('ws://localhost:8888/test', {
            realm: 'realm1',
            serializer: new MsgpackSerializer(),
            ws: w3cwebsocket,
            onConnect: () => {
                server.register('sayhello', {
                    rpc: () => {
                        return { argsList: 'hello' };
                    },
                    onSuccess: () => {
                        const client = new Wampy('ws://localhost:8888/test', {
                            realm: 'realm1',
                            serializer: new MsgpackSerializer(),
                            ws: w3cwebsocket,
                            onConnect: () => {
                                client.call('sayhello', [], result => {
                                    expect(result.argsList.shift()).to.equal('hello');
                                    done();
                                });
                            }
                        });
                    }
                });
            }
        });

    });
});
<|endoftext|>


<commit_before>import { test } from 'qunit';
import moduleForAcceptance from '../../tests/helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | flexberry lookup');

test('visiting /flexberry-lookup', function(assert) {
  visit('acceptance-tests/flexberry-lookup/settings-example');

  andThen(function() {
    assert.equal(currentURL(), 'acceptance-tests/flexberry-lookup/settings-example');
  });
});
<commit_msg>Add flexberry-lookup autocomlete test<commit_after>import Ember from 'ember';
import { test } from 'qunit';
import moduleForAcceptance from '../../tests/helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | flexberry lookup');
/*
test('visiting flexberry-lookup', function(assert) {
  assert.expect(3);

  visit('components-acceptance-tests/flexberry-lookup/settings-example');

  andThen(function() {

    let expandAnimationCompleted = new Ember.RSVP.Promise((resolve, reject) => {

      assert.equal(currentURL(), 'components-acceptance-tests/flexberry-lookup/settings-example');

      let $lookupButtouChoose = Ember.$('.lookup-choose-button');

      Ember.run(() => {
        $lookupButtouChoose.click();
      });

      Ember.run(() => {
        var done = assert.async();
        setTimeout(function() {

          let $modal = Ember.$('.flexberry-modal');
          let $modalHeader = Ember.$('.header');

          assert.strictEqual($modal.length === 1, true, 'Component open flexberry-modal block');
          assert.strictEqual($modalHeader.text().trim(), 'Temp title', 'Component flexberry-modal has title');

          done();
          resolve();
        }, 200);
      });
    });

    expandAnimationCompleted.then(() => {
      Ember.run(() => {
        let $modalCloseIcon = Ember.$('.close.icon');
        $modalCloseIcon.click();
      });

      Ember.run(() => {
        var endClose = assert.async();
        setTimeout(function() { endClose(); }, 100);
      });
    });
  });
});*/

test('visiting flexberry-lookup autocomplete', function(assert) {
  assert.expect(1);

  visit('components-acceptance-tests/flexberry-lookup/settings-example-autocomplete');

  andThen(function() {

    let expandAnimationCompleted = new Ember.RSVP.Promise((resolve, reject) => {

      assert.equal(currentURL(), 'components-acceptance-tests/flexberry-lookup/settings-example-autocomplete');

      let $lookupButtouChoose = Ember.$('.lookup-choose-button');

      Ember.run(() => {
        $lookupButtouChoose.click();
      });

      Ember.run(() => {
        var done = assert.async();
        setTimeout(function() {

          let $modal = Ember.$('.flexberry-modal');

          done();
          resolve();
        }, 200);
      });
    });

    expandAnimationCompleted.then(() => {
      Ember.run(() => {
        let $modalCloseIcon = Ember.$('.close.icon');
        $modalCloseIcon.click();
      });

      Ember.run(() => {
        var endClose = assert.async();
        setTimeout(function() { endClose(); }, 100);
      });
    });
  });
});

/*
test('set title', function(assert) {
  assert.expect(2);

  visit('components-acceptance-tests/flexberry-lookup/base-operations');

  andThen(function() {

    let expandAnimationCompleted = new Ember.RSVP.Promise((resolve, reject) => {

      let $lookupButtouChoose = Ember.$('.lookup-choose-button');
      let $ = Ember.$('.lookup-choose-button');
      assert.equal(currentURL(), 'components-acceptance-tests/flexberry-lookup/base-operations');

      Ember.run(() => {
        $lookupButtouChoose.click();
      });

      Ember.run(() => {
        var done = assert.async();
        setTimeout(function() {

          let $modal = Ember.$('.flexberry-modal');
          let $modalTitle = $modal.children('.header');
          let $modalField = $modal.children('tr');

          assert.strictEqual($modalTitle.text().trim(), 'Temp title', 'Component\'s container has title \'Temp title\' text');

          done();
          resolve();

        }, 100);
      });
    });

    expandAnimationCompleted.then(() => {
      Ember.run(() => {
        let $modalCloseIcon = Ember.$('.close.icon');
        $modalCloseIcon.click();
      });

      Ember.run(() => {
        var endClose = assert.async();
        setTimeout(function() { endClose(); }, 100);
      });
    });
  });
});*/
<|endoftext|>


<commit_before>/*jslint indent: 2, node: true */
/*global require: false, process: false */

// parseCSVBill.js
//
// Parse the billing detail from Azure so we know what to charge our customers.
//
var path = require('path'),
  fs = require('fs'),
  parseCSV = require('../common/parseCSV.js'),
  argv = process.argv,
  argc = argv.length,
  verbose = false,
  echo = function () {
    if (verbose) {
      console.log.apply(null, arguments);
    }
  },
  trimQuotes = function (column) {
    "use strict";

    if (column.length > 1) {
      if (column[0] === column[column.length - 1] && column[0] === '"') {
        return trimQuotes(column.slice(1, -1));
      }
    }
    return column;
  },
  formatDollars = function (number) {
    "use strict";

    return "$" + (Math.round(number * 100) / 100) + " USD";
  },
  parseBillLine = function (line, n) {
    "use strict";

    var item = {};

    this.state = this.state || 0;
    this.csv = this.csv || {};
    this.section = this.section || "";
    this.labels = this.labels || [];

    switch (this.state) {
    case 0: // Looking for next section
      if (line.length === 1 && line[0] !== "") {
        echo("Found section: ", line[0]);
        this.section = line[0];
        this.csv[this.section] = [];
        this.state = 1;
      }
      break;
    case 1: // record labels
      echo("Recording Label: ", line);
      this.labels = line;
      this.state = 2;
      break;
    case 2: // record item
      if (this.labels.length !== line.length) {
        if (line.length !== 1) {
          console.log("ERROR: (line %s) Bill is not formatted correctly [%s]", n, line);
          this.state = 3;
        } else {
          this.state = 0;
        }
      } else {
        item = {};
        this.labels.forEach(function (label, i) {
          item[label] = trimQuotes(line[i]);
        });
        echo("Recording item: ", item);
        this.csv[this.section].push(item);
      }
      break;
    case 3: // ERROR state
      break;
    default:
      break;
    }
  },
  parseBill = function (data) {
    "use strict";

    var context = {};

    data = parseCSV(data);
    data.forEach(parseBillLine, context);

    if (context.state !== 3) {
      return context.csv;
    }

    return null;
  },
  subTotalBill = function (bill) {
    "use strict";

    bill.Subtotals = {};
    bill.Totals = {};

    bill["Daily Usage"].forEach(function (current) {
      var MeterName = current["Meter Name"],
        ConsumedQuantity = Number(current["Consumed Quantity"]),
        InstanceId = current["Instance Id"];

      echo("Accumulating Subtotal: ", InstanceId, MeterName, ConsumedQuantity);
      bill.Subtotals[InstanceId] = bill.Subtotals[InstanceId] || {};
      bill.Subtotals[InstanceId][MeterName] = bill.Subtotals[InstanceId][MeterName] || 0;
      bill.Subtotals[InstanceId][MeterName] += ConsumedQuantity;

      echo("Accumulating Total: ", MeterName, ConsumedQuantity);
      bill.Totals[MeterName] = bill.Totals[MeterName] || {};
      bill.Totals[MeterName].AggregateTotal = bill.Totals[MeterName].AggregateTotal || 0;
      bill.Totals[MeterName].AggregateTotal += ConsumedQuantity;
    });
  },
  totalBill = function (bill) {
    "use strict";

    bill.Statement.forEach(function (current) {
      var MeterName = current["Meter Name"],
        ConsumedQuantity = Number(current["Consumed Quantity"]),
        Cost = Number(current.Value.slice(1, -4).replace(/\,/g, ""));

      echo("Recording Total: ", MeterName, ConsumedQuantity, Cost);

      bill.Totals[MeterName] = bill.Totals[MeterName] || {};
      bill.Totals[MeterName].Total = ConsumedQuantity;
      bill.Totals[MeterName].Cost = Cost;
    });
  },
  calculateReport = function (bill) {
    "use strict";

    var InstanceId = "",
      AggregateCost = 0,
      MeterName = "",
      ConsumedQuantity = 0,
      TotalQuantity = 0,
      TotalCost = 0,
      Cost = 0;

    for (InstanceId in bill.Subtotals) {
      if (bill.Subtotals.hasOwnProperty(InstanceId)) {
        console.log("------------------------------------------------------------");
        console.log("Charges for " + InstanceId);
        AggregateCost = 0;

        for (MeterName in bill.Subtotals[InstanceId]) {
          if (bill.Subtotals[InstanceId].hasOwnProperty(MeterName)) {
            ConsumedQuantity = bill.Subtotals[InstanceId][MeterName];
            TotalQuantity = bill.Totals[MeterName].AggregateTotal;
            TotalCost = bill.Totals[MeterName].Cost;
            Cost = TotalCost * (ConsumedQuantity / TotalQuantity);
            AggregateCost += Cost;

            console.log("    " + MeterName + " @ " + ConsumedQuantity + "/" + TotalQuantity + " = " + formatDollars(Cost) + " (of " + formatDollars(TotalCost) + ")");
          }
        }

        console.log("    Aggregated Cost = " + formatDollars(AggregateCost));
      }
    }
  },
  main = function (argc, argv) {
    "use strict";

    var bill = {};

    if (argc !== 3) {
      console.log('usage: %s %s <filename>', argv[0], argv[1]);
    } else {
      fs.readFile(path.resolve(".", argv[2]), { 'encoding': "utf8" }, function (err, data) {
        if (err) {
          console.log('ERROR: failed to read file');
        } else {
          bill = parseBill(data);
          if (bill && bill.hasOwnProperty("Statement") && bill.hasOwnProperty("Daily Usage")) {
            subTotalBill(bill);
            totalBill(bill);
            calculateReport(bill);
          }
        }
      });
    }
  };

main(argc, argv);
<commit_msg>Update billing parser<commit_after>/*jslint indent: 2, node: true */
/*global require: false, process: false */

// parseCSVBill.js
//
// Parse the billing detail from Azure so we know what to charge our customers.
//
var path = require('path'),
  fs = require('fs'),
  parseCSV = require('../common/parseCSV.js'),
  argv = process.argv,
  argc = argv.length,
  verbose = false,
  echo = function () {
    if (verbose) {
      console.log.apply(null, arguments);
    }
  },
  trimQuotes = function (column) {
    "use strict";

    if (column.length > 1) {
      if (column[0] === column[column.length - 1] && column[0] === '"') {
        return trimQuotes(column.slice(1, -1));
      }
    }
    return column;
  },
  formatDollars = function (number) {
    "use strict";

    return "$" + (Math.round(number * 100) / 100) + " USD";
  },
  parseBillLine = function (line, n) {
    "use strict";

    var item = {};

    this.state = this.state || 0;
    this.csv = this.csv || {};
    this.section = this.section || "";
    this.labels = this.labels || [];

    switch (this.state) {
    case 0: // Looking for next section
      if (line.length === 1 && line[0] !== "") {
        echo("Found section: ", line[0]);
        this.section = line[0];
        this.csv[this.section] = [];
        this.state = 1;
      }
      break;
    case 1: // record labels
      echo("Recording Label: ", line);
      this.labels = line;
      this.state = 2;
      break;
    case 2: // record item
      if (this.labels.length !== line.length) {
        if (line.length !== 1) {
          console.log("ERROR: (line %s) Bill is not formatted correctly [%s]", n, line);
          this.state = 3;
        } else {
          this.state = 0;
        }
      } else {
        item = {};
        this.labels.forEach(function (label, i) {
          item[label] = trimQuotes(line[i]);
        });
        echo("Recording item: ", item);
        this.csv[this.section].push(item);
      }
      break;
    case 3: // ERROR state
      break;
    default:
      break;
    }
  },
  parseBill = function (data) {
    "use strict";

    var context = {};

    data = parseCSV(data);
    data.forEach(parseBillLine, context);

    if (context.state !== 3) {
      return context.csv;
    }

    return null;
  },
  subTotalBill = function (bill) {
    "use strict";

    bill.Subtotals = {};
    bill.Totals = {};

    bill["Daily Usage"].forEach(function (current) {
      var ItemName = current["Meter Category"] + " - " + current["Meter Name"],
        ConsumedQuantity = Number(current["Consumed Quantity"]),
        InstanceId = current["Instance Id"];

      echo("Accumulating Subtotal: ", InstanceId, ItemName, ConsumedQuantity);
      bill.Subtotals[InstanceId] = bill.Subtotals[InstanceId] || {};
      bill.Subtotals[InstanceId][ItemName] = bill.Subtotals[InstanceId][ItemName] || 0;
      bill.Subtotals[InstanceId][ItemName] += ConsumedQuantity;

      echo("Accumulating Total: ", ItemName, ConsumedQuantity);
      bill.Totals[ItemName] = bill.Totals[ItemName] || {};
      bill.Totals[ItemName].AggregateTotal = bill.Totals[ItemName].AggregateTotal || 0;
      bill.Totals[ItemName].AggregateTotal += ConsumedQuantity;
    });
  },
  totalBill = function (bill) {
    "use strict";

    bill.Statement.forEach(function (current) {
      var ItemName = current["Meter Category"] + " - " + current["Meter Name"],
        ConsumedQuantity = Number(current["Consumed Quantity"]),
        Cost = Number(current.Value.slice(1, -4).replace(/\,/g, ""));

      echo("Recording Total: ", ItemName, ConsumedQuantity, Cost);

      bill.Totals[ItemName] = bill.Totals[ItemName] || {};
      bill.Totals[ItemName].Total = ConsumedQuantity;
      bill.Totals[ItemName].Cost = Cost;
    });
  },
  calculateReport = function (bill) {
    "use strict";

    var InstanceId = "",
      AggregateCost = 0,
      ItemName = "",
      ConsumedQuantity = 0,
      TotalQuantity = 0,
      TotalCost = 0,
      Cost = 0;

    for (InstanceId in bill.Subtotals) {
      if (bill.Subtotals.hasOwnProperty(InstanceId)) {
        console.log("------------------------------------------------------------");
        console.log("Charges for " + InstanceId);
        AggregateCost = 0;

        for (ItemName in bill.Subtotals[InstanceId]) {
          if (bill.Subtotals[InstanceId].hasOwnProperty(ItemName)) {
            ConsumedQuantity = bill.Subtotals[InstanceId][ItemName];
            TotalQuantity = bill.Totals[ItemName].AggregateTotal;
            TotalCost = bill.Totals[ItemName].Cost;
            Cost = TotalCost * (ConsumedQuantity / TotalQuantity);
            AggregateCost += Cost;

            console.log("    " + ItemName + " @ " + ConsumedQuantity + "/" + TotalQuantity + " = " + formatDollars(Cost) + " (of " + formatDollars(TotalCost) + ")");
          }
        }

        console.log("    Aggregated Cost = " + formatDollars(AggregateCost));
      }
    }
  },
  main = function (argc, argv) {
    "use strict";

    var bill = {};

    if (argc !== 3) {
      console.log('usage: %s %s <filename>', argv[0], argv[1]);
    } else {
      fs.readFile(path.resolve(".", argv[2]), { 'encoding': "utf8" }, function (err, data) {
        if (err) {
          console.log('ERROR: failed to read file');
        } else {
          bill = parseBill(data);
          if (bill && bill.hasOwnProperty("Statement") && bill.hasOwnProperty("Daily Usage")) {
            subTotalBill(bill);
            totalBill(bill);
            calculateReport(bill);
          }
        }
      });
    }
  };

main(argc, argv);
<|endoftext|>


<commit_before>require("./_defines");

var steps = function(){
    step1();
};
var step1 = function(){
    this.fn = require("./release/generate-minified-css");
    this.fn(step2);
};
var step2 = function(){
    this.fn = require("./release/generate-compiled-js");
    this.fn(step3);
};
var step3 = function(){
    this.fn = require("./release/update-xml-metadata");
    this.fn(step4);
};
var step4 = function(){
    this.fn = require("./release/update-html-description");
    this.fn(step5);
};
var step5 = function(){
    this.fn = require("./release/create-package-archive");
    this.fn(step6);
};
var step6 = function(){
    console.log("===> Complete");
};

steps.apply(null, []);<commit_msg>Travis CI: Added environment check for release build<commit_after>require("./_defines");

var steps = function(){
    step1();
};
var step1 = function(){
    this.fn = require("./release/generate-minified-css");
    this.fn(step2);
};
var step2 = function(){
    this.fn = require("./release/generate-compiled-js");
    this.fn(step3);
};
var step3 = function(){
    this.fn = require("./release/update-xml-metadata");
    this.fn(step4);
};
var step4 = function(){
    this.fn = require("./release/update-html-description");
    this.fn(step5);
};
var step5 = function(){
    this.fn = require("./release/create-package-archive");
    this.fn(step6);
};
var step6 = function(){
    console.log("===> Complete");
};

if (process && process.env && process.env.TRAVIS_TAG){
    console.log("Release Deployment");
    steps.apply(null, []);
}<|endoftext|>