<commit_before>/*jshint indent:2, curly:true eqeqeq:true, immed:true, latedef:true,
newcap:true, noarg:true, regexp:true, undef:true, strict:true, trailing:true
white:true*/
/*global XT:true, XM:true, Backbone:true, _:true, console:true */

(function () {
  "use strict";

  /**
    @class

    @extends XT.Model
  */
  XM.Country = XT.Model.extend({
    /** @scope XM.Country.prototype */

    recordType: 'XM.Country',

    privileges: {
      "all": {
        "create": "MaintainCountries",
        "read": true,
        "update": "MaintainCountries",
        "delete": "MaintainCountries"
      }
    },

    requiredAttributes: [
      "abbreviation",
      "currencyAbbreviation",
      "name"
    ],

    // ..........................................................
    // METHODS
    //

    validateEdit: function (attributes) {
      var params = {};

      if (attributes.abbreviation &&
          attributes.abbreviation.length !== 2) {
        params.attr = "_abbreviation".loc();
        params.length = "2";
        return XT.Error.clone('xt1006', { params: params });
      }

      if (attributes.currencyAbbreviation &&
          attributes.currencyAbbreviation.length !== 3) {
        params.attr = "_currencyAbbreviation".loc();
        params.length = "3";
        return XT.Error.clone('xt1006', { params: params });
      }
    }

  });

  /**
    @class

    @extends XT.Model
  */
  XM.State = XT.Model.extend({
    /** @scope XM.State.prototype */

    recordType: 'XM.State',

    privileges: {
      "all": {
        "create": "MaintainStates",
        "read": true,
        "update": "MaintainStates",
        "delete": "MaintainStates"
      }
    },

    requiredAttributes: [
      "abbreviation",
      "country",
      "name"
    ],

    relations: [{
      type: Backbone.HasOne,
      key: 'country',
      relatedModel: 'XM.Country',
      includeInJSON: 'guid'
    }]

  });

  /**
    @class

    @extends XM.Document
  */
  XM.Address = XM.Document.extend({
    /** @scope XM.Address.prototype */

    recordType: 'XM.Address',

    numberPolicy: XM.Document.AUTO_NUMBER,

    privileges: {
      "all": {
        "create": "MaintainAddresses",
        "read": "ViewAddresses",
        "update": "MaintainAddresses",
        "delete": "MaintainAddresses"
      }
    },

    relations: [{
      type: Backbone.HasMany,
      key: 'comments',
      relatedModel: 'XM.AddressComment',
      reverseRelation: {
        key: 'address'
      }
    }, {
      type: Backbone.HasMany,
      key: 'characteristics',
      relatedModel: 'XM.AddressCharacteristic',
      reverseRelation: {
        key: 'address'
      }
    }],

    // ..........................................................
    // METHODS
    //

    /**
      Success response returns an integer from the server indicating how many times the address
      is used by other records.

      @param {Object} Options
      @returns Receiver
    */
    useCount: function (options) {
      console.log("XM.Address.useCount for: " + this.id);
      XT.dataSource.dispatch('XM.Address', 'useCount', this.id, options);
      return this;
    }

  });

  // ..........................................................
  // CLASS METHODS
  //

  _.extend(XM.Address, {

    /**
      Success response returns an address id for an address with the same fields
      as those passed.

      @param {String} Line1
      @param {String} Line2
      @param {String} Line3
      @param {String} City
      @param {String} State
      @param {String} Postal Code
      @param {String} Country
      @param {Object} Options
      @returns Receiver
    */
    findExisting: function (line1, line2, line3, city, state, postalcode, country, options) {
      var params = {
          type: 'Address',
          line1: line1,
          line2: line2,
          line3: line3,
          city: city,
          state: state,
          postalcode: postalcode,
          country: country
        };
      XT.dataSource.dispatch('XM.Address', 'findExisting', params, options);
      console.log("XM.Address.findExisting");
      return this;
    }

  });

  /**
    @class

    @extends XT.Model
  */
  XM.AddressComment = XT.Model.extend({
    /** @scope XM.AddressComment.prototype */

    recordType: 'XM.AddressComment'

  });

  /**
    @class

    @extends XT.Model
  */
  XM.AddressCharacteristic = XT.Model.extend({
    /** @scope XM.AddressCharacteristic.prototype */

    recordType: 'XM.AddressCharacteristic'

  });

  /**
    @class

    @extends XT.Model
  */
  XM.AddressInfo = XT.Model.extend({
    /** @scope XM.AddressInfo.prototype */

    recordType: 'XM.AddressInfo',

    readOnly: true,

    privileges: {
      "all": {
        "create": false,
        "read": true,
        "update": false,
        "delete": false
      }
    }

  });

  // ..........................................................
  // COLLECTIONS
  //

  /**
    @class

    @extends XT.Collection
  */
  XM.AddressInfoCollection = XT.Collection.extend({
    /** @scope XM.AddressInfoCollection.prototype */

    model: XM.AddressInfo

  });

  /**
    @class

    @extends XT.Collection
  */
  XM.CountryCollection = XT.Collection.extend({
    /** @scope XM.CountryCollection.prototype */

    model: XM.Country

  });

  /**
    @class

    @extends XT.Collection
  */
  XM.StateCollection = XT.Collection.extend({
    /** @scope XM.StateCollection.prototype */

    model: XM.State

  });

}());
<commit_msg>add format functions in address.<commit_after>/*jshint indent:2, curly:true eqeqeq:true, immed:true, latedef:true,
newcap:true, noarg:true, regexp:true, undef:true, strict:true, trailing:true
white:true*/
/*global XT:true, XM:true, Backbone:true, _:true, console:true */

(function () {
  "use strict";

  /**
    @class

    @extends XT.Model
  */
  XM.Country = XT.Model.extend({
    /** @scope XM.Country.prototype */

    recordType: 'XM.Country',

    privileges: {
      "all": {
        "create": "MaintainCountries",
        "read": true,
        "update": "MaintainCountries",
        "delete": "MaintainCountries"
      }
    },

    requiredAttributes: [
      "abbreviation",
      "currencyAbbreviation",
      "name"
    ],

    // ..........................................................
    // METHODS
    //

    validateEdit: function (attributes) {
      var params = {};

      if (attributes.abbreviation &&
          attributes.abbreviation.length !== 2) {
        params.attr = "_abbreviation".loc();
        params.length = "2";
        return XT.Error.clone('xt1006', { params: params });
      }

      if (attributes.currencyAbbreviation &&
          attributes.currencyAbbreviation.length !== 3) {
        params.attr = "_currencyAbbreviation".loc();
        params.length = "3";
        return XT.Error.clone('xt1006', { params: params });
      }
    }

  });

  /**
    @class

    @extends XT.Model
  */
  XM.State = XT.Model.extend({
    /** @scope XM.State.prototype */

    recordType: 'XM.State',

    privileges: {
      "all": {
        "create": "MaintainStates",
        "read": true,
        "update": "MaintainStates",
        "delete": "MaintainStates"
      }
    },

    requiredAttributes: [
      "abbreviation",
      "country",
      "name"
    ],

    relations: [{
      type: Backbone.HasOne,
      key: 'country',
      relatedModel: 'XM.Country',
      includeInJSON: 'guid'
    }]

  });

  /**
    @class

    @extends XM.Document
  */
  XM.Address = XM.Document.extend({
    /** @scope XM.Address.prototype */

    recordType: 'XM.Address',

    numberPolicy: XM.Document.AUTO_NUMBER,

    privileges: {
      "all": {
        "create": "MaintainAddresses",
        "read": "ViewAddresses",
        "update": "MaintainAddresses",
        "delete": "MaintainAddresses"
      }
    },

    relations: [{
      type: Backbone.HasMany,
      key: 'comments',
      relatedModel: 'XM.AddressComment',
      reverseRelation: {
        key: 'address'
      }
    }, {
      type: Backbone.HasMany,
      key: 'characteristics',
      relatedModel: 'XM.AddressCharacteristic',
      reverseRelation: {
        key: 'address'
      }
    }],

    // ..........................................................
    // METHODS
    //

    /**
      Formats the multiple lines of an address into a
      text block separating the elements of the address by line breaks.

      @params {Boolean} Is HTML
      @return {String}
    */
    format: function (isHtml) {
      return XM.Address.format(this, isHtml);
    },

    /**
      A formatted address that includes city, state and country.

      @return {String}
    */
    formatShort: function () {
      return XM.Address.formatShort(this);
    },

    /**
      Success response returns an integer from the server indicating how many times the address
      is used by other records.

      @param {Object} Options
      @returns Receiver
    */
    useCount: function (options) {
      console.log("XM.Address.useCount for: " + this.id);
      XT.dataSource.dispatch('XM.Address', 'useCount', this.id, options);
      return this;
    }

  });

  // ..........................................................
  // CLASS METHODS
  //

  _.extend(XM.Address, {

    /**
      Success response returns an address id for an address with the same fields
      as those passed.

      @param {String} Line1
      @param {String} Line2
      @param {String} Line3
      @param {String} City
      @param {String} State
      @param {String} Postal Code
      @param {String} Country
      @param {Object} Options
      @returns Receiver
    */
    findExisting: function (line1, line2, line3, city, state, postalcode, country, options) {
      var params = {
          type: 'Address',
          line1: line1,
          line2: line2,
          line3: line3,
          city: city,
          state: state,
          postalcode: postalcode,
          country: country
        };
      XT.dataSource.dispatch('XM.Address', 'findExisting', params, options);
      console.log("XM.Address.findExisting");
      return this;
    },

    /**
      This function formats the multiple lines of an address into a
      text block separating the elements of the address by line breaks.

      Address format accepts multiple argument formats:
        XM.Address.format(address);
        XM.Address.format(address, isHtml);
        XM.Address.format(name, line1, line2, line3, city, state, postalcode, country);
        XM.Address.format(name, line1, line2, line3, city, state, postalcode, country, isHtml);

      Where address is an XM.Address and isHtml determines whether to
      use HTML line breaks instead of ASCII new line characters. The
      default for isHtml is false. The longer signatures accept string
      components of an address.

      @return {String}
    */
    format: function () {
      var fmtlines   = [],
        name, line1, line2, line3,
        city, state, postalcode, country,
        breaks, result = '', csz;

      if (typeof arguments[0] === 'object') {
        name = '';
        line1 = arguments[0].get('line1');
        line2 = arguments[0].get('line2');
        line3 = arguments[0].get('line3');
        city = arguments[0].get('city');
        state = arguments[0].get('state');
        postalcode = arguments[0].get('postalcode');
        country = arguments[0].get('country');
        breaks = (arguments[1] === undefined ? false : arguments[1]) ? '
' : '\n';
      } else if (typeof arguments[0] === 'string')  {
        name = arguments[0];
        line1 = arguments[1];
        line2 = arguments[2];
        line3 = arguments[3];
        city = arguments[4];
        state = arguments[5];
        postalcode = arguments[6];
        country = arguments[7];
        breaks = (arguments[8] === undefined ? false : arguments[8]) ? '
' : '\n';
      } else { return false; }

      if (name) { fmtlines.push(name); }
      if (line1) { fmtlines.push(line1); }
      if (line2) { fmtlines.push(line2); }
      if (line3) { fmtlines.push(line3); }
      if (city || state || postalcode) {
        csz = (city || '') +
              (city && (state || postalcode) ? ', '  : '') +
              (state || '') +
              (state && postalcode ? ' '  : '') +
              (postalcode || '');
        fmtlines.push(csz);
      }
      if (country) { fmtlines.push(country); }

      if (fmtlines.length) { result = fmtlines.join(breaks); }

      return result;
    },

    /**
      A formatted address that includes city, state and country.

      @return {String}
    */
    formatShort: function (address) {
      var ret,
        city = address.get('city') || '',
        state = address.get('state') || '',
        country = address.get('country') || '';
      ret = city + (city && state ? ', ' : '') + state;
      ret += (ret ? ' ' : '') + country;
      return ret;
    }

  });

  /**
    @class

    @extends XT.Model
  */
  XM.AddressComment = XT.Model.extend({
    /** @scope XM.AddressComment.prototype */

    recordType: 'XM.AddressComment'

  });

  /**
    @class

    @extends XT.Model
  */
  XM.AddressCharacteristic = XT.Model.extend({
    /** @scope XM.AddressCharacteristic.prototype */

    recordType: 'XM.AddressCharacteristic'

  });

  /**
    @class

    @extends XT.Model
  */
  XM.AddressInfo = XT.Model.extend({
    /** @scope XM.AddressInfo.prototype */

    recordType: 'XM.AddressInfo',

    readOnly: true,

    privileges: {
      "all": {
        "create": false,
        "read": true,
        "update": false,
        "delete": false
      }
    },

    // ..........................................................
    // METHODS
    //

    /**
      Formats the multiple lines of an address into a
      text block separating the elements of the address by line breaks.

      @params {Boolean} Is HTML
      @return {String}
    */
    format: function (isHtml) {
      return XM.Address.format(this, isHtml);
    },

    /**
      A formatted address that includes city, state and country.

      @return {String}
    */
    formatShort: function () {
      return XM.Address.formatShort(this);
    }

  });

  // ..........................................................
  // COLLECTIONS
  //

  /**
    @class

    @extends XT.Collection
  */
  XM.AddressInfoCollection = XT.Collection.extend({
    /** @scope XM.AddressInfoCollection.prototype */

    model: XM.AddressInfo

  });

  /**
    @class

    @extends XT.Collection
  */
  XM.CountryCollection = XT.Collection.extend({
    /** @scope XM.CountryCollection.prototype */

    model: XM.Country

  });

  /**
    @class

    @extends XT.Collection
  */
  XM.StateCollection = XT.Collection.extend({
    /** @scope XM.StateCollection.prototype */

    model: XM.State

  });

}());
<|endoftext|>


<commit_before>'use strict';

/**
 * Permits declarative (and dynamic) definitions of tab links with full routes.
 *
 * requires 'ui.router' and 'ui.bootstrap'
 * (uses tabset and tab directives in ui.bootstrap and route changes in ui.router)
 *
 * You can define (for styling) the attributes type="pills" and vertical="true | false" and justified="true | false"
 * You can also specify arbitrary CSS classes to be added to each tab by providing them as values with the "class" parameter
 *
 * Watches the $stateChangeXX events so it can update the parent tab(s) when using $state.go or ui-sref anchors.
 *
 * See ui-router-tabs.spec.js for tests.
 *
 * Author: Robert Pocklington (rpocklin@gmail.com)
 * License: MIT
 *
 */

/* Common.js package manager support (e.g. ComponentJS, WebPack) */
if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.exports === exports) {
  module.exports = 'ui.router.tabs';
}

angular.module('ui.router.tabs', []);
angular.module('ui.router.tabs').directive(
  'tabs', ['$rootScope', '$state', function($rootScope, $state) {

    return {
      restrict: 'E',
      scope: {
        tabs: '=data',
        type: '@',
        justified: '@',
        vertical: '@',
        class: '@'
      },
      link: function(scope) {

        var updateTabs = function() {
          scope.update_tabs();
        };

        var unbindStateChangeSuccess = $rootScope.$on('$stateChangeSuccess', updateTabs);
        var unbindStateChangeError = $rootScope.$on('$stateChangeError', updateTabs);
        var unbindStateChangeCancel = $rootScope.$on('$stateChangeCancel', updateTabs);
        var unbindStateNotFound = $rootScope.$on('$stateNotFound', updateTabs);

        scope.$on('$destroy', unbindStateChangeSuccess);
        scope.$on('$destroy', unbindStateChangeError);
        scope.$on('$destroy', unbindStateChangeCancel);
        scope.$on('$destroy', unbindStateNotFound);
      },
      controller: ['$scope', function($scope) {

        if (!$scope.tabs) {
          throw new Error('UI Router Tabs: \'data\' attribute not defined, please check documentation for how to use this directive.');
        }

        if (!angular.isArray($scope.tabs)) {
          throw new Error('UI Router Tabs: \'data\' attribute must be an array of tab data with at least one tab defined.');
        }

        var currentStateEqualTo = function(tab) {

          var isEqual = $state.is(tab.route, tab.params, tab.options);
          return isEqual;
        };

        $scope.go = function(tab) {

          if (!currentStateEqualTo(tab) && !tab.disable) {
            $state.go(tab.route, tab.params, tab.options);
          }
        };

        /* whether to highlight given route as part of the current state */
        $scope.active = function(tab) {

          var isAncestorOfCurrentRoute = $state.includes(tab.route, tab.params, tab.options);
          return isAncestorOfCurrentRoute;
        };

        $scope.update_tabs = function() {

          // sets which tab is active (used for highlighting)
          angular.forEach($scope.tabs, function(tab) {
            tab.params = tab.params || {};
            tab.options = tab.options || {};
            tab.active = $scope.active(tab);
          });
        };

        $scope.update_tabs();
    }],
      templateUrl: function(element, attributes) {
        return attributes.templateUrl || 'ui-router-tabs-default-template.html';
      }
    };
}]
).run(
['$templateCache', function($templateCache) {
    var CUSTOM_UI_VIEW_TEMPLATE = '
<uib-tabset class="tab-container" type="{{type}}" vertical="{{vertical}}" ' +
      'justified="{{justified}}" class="{{class}}">' +
      '<uib-tab class="tab" ng-repeat="tab in tabs" heading="{{tab.heading}}" ' +
      'active="tab.active" disable="tab.disable" ng-click="go(tab)">' +
      '</uib-tab>' +
      '</uib-tabset>' +
      '
';

    var INLINE_TEMPLATE =
      '
 ' +
      '<uib-tabset class="tab-container" type="{{type}}" vertical="{{vertical}}" justified="{{justified}}">' + '<uib-tabset class="tab-container" type="{{type}}" vertical="{{vertical}}" justified="{{justified}}">' +
      '<uib-tab class="tab" ng-repeat="tab in tabs" heading="{{tab.heading}}" active="tab.active" disable="tab.disable" ng-click="go(tab)">' +
      '<ui-view ng-if="withUiView" />' +
      '</uib-tab>' +
      '</uib-tabset>' +
      '
';

    $templateCache.put('ui-router-tabs-custom-ui-view-template.html', CUSTOM_UI_VIEW_TEMPLATE);
    $templateCache.put('ui-router-tabs-default-template.html', INLINE_TEMPLATE);
}]
);
<commit_msg>Tidying up html formatting.<commit_after>'use strict';

/**
 * Permits declarative (and dynamic) definitions of tab links with full routes.
 *
 * requires 'ui.router' and 'ui.bootstrap'
 * (uses tabset and tab directives in ui.bootstrap and route changes in ui.router)
 *
 * You can define (for styling) the attributes type="pills" and vertical="true | false" and justified="true | false"
 * You can also specify arbitrary CSS classes to be added to each tab by providing them as values with the "class" parameter
 *
 * Watches the $stateChangeXX events so it can update the parent tab(s) when using $state.go or ui-sref anchors.
 *
 * See ui-router-tabs.spec.js for tests.
 *
 * Author: Robert Pocklington (rpocklin@gmail.com)
 * License: MIT
 *
 */

/* Common.js package manager support (e.g. ComponentJS, WebPack) */
if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.exports === exports) {
  module.exports = 'ui.router.tabs';
}

angular.module('ui.router.tabs', []);
angular.module('ui.router.tabs').directive(
  'tabs', ['$rootScope', '$state', function($rootScope, $state) {

    return {
      restrict: 'E',
      scope: {
        tabs: '=data',
        type: '@',
        justified: '@',
        vertical: '@',
        class: '@'
      },
      link: function(scope) {

        var updateTabs = function() {
          scope.update_tabs();
        };

        var unbindStateChangeSuccess = $rootScope.$on('$stateChangeSuccess', updateTabs);
        var unbindStateChangeError = $rootScope.$on('$stateChangeError', updateTabs);
        var unbindStateChangeCancel = $rootScope.$on('$stateChangeCancel', updateTabs);
        var unbindStateNotFound = $rootScope.$on('$stateNotFound', updateTabs);

        scope.$on('$destroy', unbindStateChangeSuccess);
        scope.$on('$destroy', unbindStateChangeError);
        scope.$on('$destroy', unbindStateChangeCancel);
        scope.$on('$destroy', unbindStateNotFound);
      },
      controller: ['$scope', function($scope) {

        if (!$scope.tabs) {
          throw new Error('UI Router Tabs: \'data\' attribute not defined, please check documentation for how to use this directive.');
        }

        if (!angular.isArray($scope.tabs)) {
          throw new Error('UI Router Tabs: \'data\' attribute must be an array of tab data with at least one tab defined.');
        }

        var currentStateEqualTo = function(tab) {

          var isEqual = $state.is(tab.route, tab.params, tab.options);
          return isEqual;
        };

        $scope.go = function(tab) {

          if (!currentStateEqualTo(tab) && !tab.disable) {
            $state.go(tab.route, tab.params, tab.options);
          }
        };

        /* whether to highlight given route as part of the current state */
        $scope.active = function(tab) {

          var isAncestorOfCurrentRoute = $state.includes(tab.route, tab.params, tab.options);
          return isAncestorOfCurrentRoute;
        };

        $scope.update_tabs = function() {

          // sets which tab is active (used for highlighting)
          angular.forEach($scope.tabs, function(tab) {
            tab.params = tab.params || {};
            tab.options = tab.options || {};
            tab.active = $scope.active(tab);
          });
        };

        $scope.update_tabs();
    }],
      templateUrl: function(element, attributes) {
        return attributes.templateUrl || 'ui-router-tabs-default-template.html';
      }
    };
}]
).run(
['$templateCache', function($templateCache) {
    var CUSTOM_UI_VIEW_TEMPLATE = '
' +
      '<uib-tabset class="tab-container" type="{{type}}" vertical="{{vertical}}" justified="{{justified}}" class="{{class}}">' +
      '<uib-tab class="tab" ng-repeat="tab in tabs" heading="{{tab.heading}}" ' +
      'active="tab.active" disable="tab.disable" ng-click="go(tab)">' +
      '</uib-tab>' +
      '</uib-tabset>' +
      '
';

    var INLINE_TEMPLATE =
      '
' +
      '<uib-tabset class="tab-container" type="{{type}}" vertical="{{vertical}}" justified="{{justified}}" class="{{class}}">' +
      '<uib-tab class="tab" ng-repeat="tab in tabs" heading="{{tab.heading}}" ' +
      'active="tab.active" disable="tab.disable" ng-click="go(tab)">' +
      '<ui-view></ui-view>' +
      '</uib-tab>' +
      '</uib-tabset>' +
      '
';

    $templateCache.put('ui-router-tabs-custom-ui-view-template.html', CUSTOM_UI_VIEW_TEMPLATE);
    $templateCache.put('ui-router-tabs-default-template.html', INLINE_TEMPLATE);
}]
);
<|endoftext|>


<commit_before>import React from 'react';
import ReactDom from 'react-dom';
import { shallowRender } from '../../../src/common/Test'
import TestUtils from 'react-addons-test-utils'

import Player from '../../../src/components/player/Player'

describe('Transcript component', function () {
  let component;
  let rootElement;

  let options = {
    mediaId: 'mediaId',
    playerType: 'FileInputPlayer',
    playerState: {
      loaded: 100,
      isFullscreen: false,
      timelineWidth: 1000,
      error: "",
      playing: false,
      url: "url",
      played: 0.1,
      duration: 1000,
      type: "audio",
      utteranceTime: null
    },
    mediaState: {
      data: {
        metadata: {
          duration: 1000
        }
      },
      "transcriptSpeakers": [
        {
          "start": 0,
          "name": "Speaker 1"
        },
        {
          "start": 3000,
          "name": "Speaker 2"
        }
      ],
      "speakers": {
        "Speaker 1": {
          "name": "Speaker 1",
          "color": "#2818B0"
        },
        "Speaker 2": {
          "name": "Speaker 2",
          "color": "#21128B"
        }
      }
    },
    markersState: {
      markerIds: ['0', '1'],
      markers: {
        0: {
          id: "0",
          keywordName: "george washington",
          time: 0.71
        },
        1: {
          id: "1",
          keywordName: "george washington",
          time: 57
        }
      }
    },
    hasNextKeywordButton: true,
    hasDownloadButton: true,
    isShowKeywordsMarkers: true,
    actions: {
      setTimelineWidth: function (mediaId, width) {},
      setDuration: function (mediaId, duration) {},
      setPosition: function (mediaId, played) {},
      setBuffered: function (mediaId, loaded) {},
      setFullscreen: function (mediaId, isFullscreen) {},
      play: function (mediaId) {},
      pause: function (mediaId) {},
      clearJustCreatedMarkers: function (mediaId) {},
      clearUtteranceTime: function (mediaId) {}
    }
  };

  const getComponent = function (_options = {}) {
    let props = {
      ...options,
      ..._options
    };

    return TestUtils.renderIntoDocument(
      <Player mediaId={props.mediaId}
              playerType={props.playerType}
              playerState={props.playerState}
              mediaState={props.mediaState}
              markersState={props.markersState}
              hasNextKeywordButton={props.hasNextKeywordButton}
              hasDownloadButton={props.hasDownloadButton}
              isShowKeywordsMarkers={props.isShowKeywordsMarkers}
              actions={props.actions}
      />
    );
  };

  beforeEach(function () {
    component = getComponent();
    rootElement = ReactDom.findDOMNode(component);
  });

  it('Check root element', function() {
    assert.equal(rootElement.tagName, 'DIV');
    assert.equal(rootElement.className, 'vbs-player');
  });

  it('Check root element for video', function() {
    component = getComponent({
      ...options,
      playerState: {
        ...options.playerState,
        type: "video"
      }
    });
    rootElement = ReactDom.findDOMNode(component);
    assert.equal(rootElement.className, 'vbs-player vbs-player--video');
  });

  it('Check root element for video fullscreen', function() {
    component = getComponent({
      ...options,
      playerState: {
        ...options.playerState,
        type: "video",
        isFullscreen: true
      }
    });
    rootElement = ReactDom.findDOMNode(component);
    assert.equal(rootElement.className, 'vbs-player vbs-player--video vbs-player--fullscreen');
  });

  it('Check react-player classes for audio', function() {
    let reactPlayer = TestUtils.findRenderedDOMComponentWithClass(component, 'vbs-player__original');
    assert.equal(reactPlayer.className, 'vbs-player__original vbs-player__original--audio');
  });

  it('Check react-player classes for video', function() {
    component = getComponent({
      ...options,
      playerState: {
        ...options.playerState,
        type: "video"
      }
    });
    let reactPlayer = TestUtils.findRenderedDOMComponentWithClass(component, 'vbs-player__original');
    assert.equal(reactPlayer.className, 'vbs-player__original vbs-player__original--video');
  });

  it('Check constructor', function() {
    component.constructor();
    assert.equal(component.state.seeking, false);
    assert.equal(component.state.seekValue, 0);
    assert.equal(component.state.volume, 100);
  });

  it('check componentWillMount without mediaState', function() {
    component = getComponent({
      ...options,
      mediaState: null
    });
    assert.equal(component.componentWillMount(), false);
  });

  it('check componentWillMount without duration', function() {
    component = getComponent({
      ...options,
      mediaState: {
        ...options.mediaState,
        data: {
          metadata: {
            duration: null
          }
        }
      }
    });
    component.onDuration = sinon.spy();
    component.componentWillMount();
    assert.isFalse(component.onDuration.called);
  });

  it('check componentWillMount with duration', function() {
    component.onDuration = sinon.spy();
    component.componentWillMount();
    assert.isTrue(component.onDuration.calledOnce);
  });

  it('check togglePlay if paused', function() {
    component.onPause = sinon.spy();
    component.onPlay = sinon.spy();
    component.togglePlay();
    assert.isFalse(component.onPause.called);
    assert.isTrue(component.onPlay.calledOnce);
  });

  it('check togglePlay if played', function() {
    component = getComponent({
      ...options,
      playerState: {
        ...options.playerState,
        playing: true
      }
    });
    component.onPause = sinon.spy();
    component.onPlay = sinon.spy();
    component.togglePlay();
    assert.isFalse(component.onPlay.called);
    assert.isTrue(component.onPause.calledOnce);
  });

  it('check onDuration', function() {
    let setDuration = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setDuration
      }
    });
    component.onDuration(900);
    assert.isTrue(setDuration.calledOnce);
  });

  it('check onDuration with negative argument', function() {
    let setDuration = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setDuration
      }
    });
    component.onDuration(-1);
    assert.isFalse(setDuration.called);
  });

  it('check onDuration with same duration', function() {
    let setDuration = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setDuration
      }
    });
    component.onDuration(options.playerState.duration);
    assert.isFalse(setDuration.called);
  });

  it('check onPlay', function() {
    let play = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        play
      }
    });
    component.onPlay();
    assert.isTrue(play.calledOnce);
  });

  it('check onPause', function() {
    let pause = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        pause
      }
    });
    component.onPause();
    assert.isTrue(pause.calledOnce);
  });

  it('check onPause if loaded == 0', function() {
    let pause = sinon.spy();
    component = getComponent({
      ...options,
      playerState: {
        ...options.playerState,
        loaded: 0
      },
      actions: {
        ...options.actions,
        pause
      }
    });
    component.onPause();
    assert.isFalse(pause.called);
  });

  it('check onProgress for played', function() {
    let setPosition = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setPosition
      }
    });
    component.onProgress({played: 0.2});
    assert.isTrue(setPosition.calledOnce);
  });

  it('check onProgress for the same played', function() {
    let setPosition = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setPosition
      }
    });
    component.onProgress(options.playerState.played);
    assert.isFalse(setPosition.called);
  });

  it('check onProgress for loaded', function() {
    let setBuffered = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setBuffered
      }
    });
    component.onProgress({loaded: 200});
    assert.isTrue(setBuffered.calledOnce);
  });

  it('check onProgress for the same loaded', function() {
    let setBuffered = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setBuffered
      }
    });
    component.onProgress(options.playerState.loaded);
    assert.isFalse(setBuffered.called);
  });

  it('check onSeekMouseDown', function() {
    component.calcPosition = function () {
      return 100;
    };
    component.onSeekMouseDown();
    assert.equal(component.state.seeking, true);
    assert.equal(component.state.seekValue, 100);
  });

  it('check onSeekMouseMove with seeking == false', function() {
    component.state.seeking = false;
    component.onSeekMouseMove();
    assert.equal(component.onSeekMouseMove(), false);
  });

  it('check onSeekMouseDown', function() {
    component.calcPosition = function () {
      return 100;
    };
    component.state.seeking = true;
    component.onSeekMouseMove();
    assert.equal(component.state.seekValue, 100);
  });

  it('check onSeekMouseUp', function() {
    component.calcPosition = function () {
      return 100;
    };
    component.state.seeking = true;
    component.seekOnPosition = sinon.spy();
    component.onSeekMouseUp();
    assert.equal(component.state.seeking, false);
    assert.equal(component.seekOnPosition.calledOnce, true);
  });

  it('check onVolumeChange', function() {
    component.onVolumeChange(50);
    assert.equal(component.state.volume, 50);
  });

  it('check fullscreenPlayer', function() {
    let setFullscreen = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setFullscreen
      }
    });
    component.fullscreenPlayer();
    assert.isTrue(setFullscreen.calledOnce);
  });

  it('check exitFullscreen', function() {
    let setFullscreen = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setFullscreen
      }
    });
    component.exitFullscreen();
    assert.isTrue(setFullscreen.calledOnce);
  });

});

<commit_msg>test for Player.js<commit_after>import React from 'react';
import ReactDom from 'react-dom';
import { shallowRender } from '../../../src/common/Test'
import TestUtils from 'react-addons-test-utils'

import Player from '../../../src/components/player/Player'

describe('Transcript component', function () {
  let component;
  let rootElement;

  let options = {
    mediaId: 'mediaId',
    playerType: 'FileInputPlayer',
    playerState: {
      loaded: 100,
      isFullscreen: false,
      timelineWidth: 1000,
      error: "",
      playing: false,
      url: "url",
      played: 0.1,
      duration: 1000,
      type: "audio",
      utteranceTime: null
    },
    mediaState: {
      data: {
        metadata: {
          duration: 1000
        }
      },
      "transcriptSpeakers": [
        {
          "start": 0,
          "name": "Speaker 1"
        },
        {
          "start": 3000,
          "name": "Speaker 2"
        }
      ],
      "speakers": {
        "Speaker 1": {
          "name": "Speaker 1",
          "color": "#2818B0"
        },
        "Speaker 2": {
          "name": "Speaker 2",
          "color": "#21128B"
        }
      }
    },
    markersState: {
      markerIds: ['0', '1'],
      markers: {
        0: {
          id: "0",
          keywordName: "george washington",
          time: 0.71
        },
        1: {
          id: "1",
          keywordName: "george washington",
          time: 57
        }
      }
    },
    hasNextKeywordButton: true,
    hasDownloadButton: true,
    isShowKeywordsMarkers: true,
    actions: {
      setTimelineWidth: function (mediaId, width) {},
      setDuration: function (mediaId, duration) {},
      setPosition: function (mediaId, played) {},
      setBuffered: function (mediaId, loaded) {},
      setFullscreen: function (mediaId, isFullscreen) {},
      play: function (mediaId) {},
      pause: function (mediaId) {},
      clearJustCreatedMarkers: function (mediaId) {},
      clearUtteranceTime: function (mediaId) {}
    }
  };

  const getComponent = function (_options = {}) {
    let props = {
      ...options,
      ..._options
    };

    return TestUtils.renderIntoDocument(
      <Player mediaId={props.mediaId}
              playerType={props.playerType}
              playerState={props.playerState}
              mediaState={props.mediaState}
              markersState={props.markersState}
              hasNextKeywordButton={props.hasNextKeywordButton}
              hasDownloadButton={props.hasDownloadButton}
              isShowKeywordsMarkers={props.isShowKeywordsMarkers}
              actions={props.actions}
      />
    );
  };

  beforeEach(function () {
    component = getComponent();
    rootElement = ReactDom.findDOMNode(component);
  });

  it('Check root element', function() {
    assert.equal(rootElement.tagName, 'DIV');
    assert.equal(rootElement.className, 'vbs-player');
  });

  it('Check root element for video', function() {
    component = getComponent({
      ...options,
      playerState: {
        ...options.playerState,
        type: "video"
      }
    });
    rootElement = ReactDom.findDOMNode(component);
    assert.equal(rootElement.className, 'vbs-player vbs-player--video');
  });

  it('Check root element for video fullscreen', function() {
    component = getComponent({
      ...options,
      playerState: {
        ...options.playerState,
        type: "video",
        isFullscreen: true
      }
    });
    rootElement = ReactDom.findDOMNode(component);
    assert.equal(rootElement.className, 'vbs-player vbs-player--video vbs-player--fullscreen');
  });

  it('Check react-player classes for audio', function() {
    let reactPlayer = TestUtils.findRenderedDOMComponentWithClass(component, 'vbs-player__original');
    assert.equal(reactPlayer.className, 'vbs-player__original vbs-player__original--audio');
  });

  it('Check react-player classes for video', function() {
    component = getComponent({
      ...options,
      playerState: {
        ...options.playerState,
        type: "video"
      }
    });
    let reactPlayer = TestUtils.findRenderedDOMComponentWithClass(component, 'vbs-player__original');
    assert.equal(reactPlayer.className, 'vbs-player__original vbs-player__original--video');
  });

  it('Check constructor', function() {
    component.constructor();
    assert.equal(component.state.seeking, false);
    assert.equal(component.state.seekValue, 0);
    assert.equal(component.state.volume, 100);
  });

  it('check componentWillMount without mediaState', function() {
    component = getComponent({
      ...options,
      mediaState: null
    });
    assert.equal(component.componentWillMount(), false);
  });

  it('check componentWillMount without duration', function() {
    component = getComponent({
      ...options,
      mediaState: {
        ...options.mediaState,
        data: {
          metadata: {
            duration: null
          }
        }
      }
    });
    component.onDuration = sinon.spy();
    component.componentWillMount();
    assert.isFalse(component.onDuration.called);
  });

  it('check componentWillMount with duration', function() {
    component.onDuration = sinon.spy();
    component.componentWillMount();
    assert.isTrue(component.onDuration.calledOnce);
  });

  it('check componentDidUpdate with justCreated markers', function() {
    component = getComponent({
      ...options,
      markersState: {
        ...options.markersState,
        justCreated: true
      }
    });
    component.seekToFirstMarker = sinon.spy();
    component.componentDidUpdate();
    assert.isTrue(component.seekToFirstMarker.calledOnce);
  });

  it('check componentDidUpdate with utteranceTime', function() {
    component = getComponent({
      ...options,
      playerState: {
        ...options.markersState,
        utteranceTime: 100
      }
    });
    component.seekToUtterance = sinon.spy();
    component.componentDidUpdate();
    assert.isTrue(component.seekToUtterance.calledOnce);
  });

  it('check togglePlay if paused', function() {
    component.onPause = sinon.spy();
    component.onPlay = sinon.spy();
    component.togglePlay();
    assert.isFalse(component.onPause.called);
    assert.isTrue(component.onPlay.calledOnce);
  });

  it('check togglePlay if played', function() {
    component = getComponent({
      ...options,
      playerState: {
        ...options.playerState,
        playing: true
      }
    });
    component.onPause = sinon.spy();
    component.onPlay = sinon.spy();
    component.togglePlay();
    assert.isFalse(component.onPlay.called);
    assert.isTrue(component.onPause.calledOnce);
  });

  it('check onDuration', function() {
    let setDuration = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setDuration
      }
    });
    component.onDuration(900);
    assert.isTrue(setDuration.calledOnce);
  });

  it('check onDuration with negative argument', function() {
    let setDuration = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setDuration
      }
    });
    component.onDuration(-1);
    assert.isFalse(setDuration.called);
  });

  it('check onDuration with same duration', function() {
    let setDuration = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setDuration
      }
    });
    component.onDuration(options.playerState.duration);
    assert.isFalse(setDuration.called);
  });

  it('check onPlay', function() {
    let play = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        play
      }
    });
    component.onPlay();
    assert.isTrue(play.calledOnce);
  });

  it('check onPause', function() {
    let pause = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        pause
      }
    });
    component.onPause();
    assert.isTrue(pause.calledOnce);
  });

  it('check onPause if loaded == 0', function() {
    let pause = sinon.spy();
    component = getComponent({
      ...options,
      playerState: {
        ...options.playerState,
        loaded: 0
      },
      actions: {
        ...options.actions,
        pause
      }
    });
    component.onPause();
    assert.isFalse(pause.called);
  });

  it('check onProgress for played', function() {
    let setPosition = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setPosition
      }
    });
    component.onProgress({played: 0.2});
    assert.isTrue(setPosition.calledOnce);
  });

  it('check onProgress for the same played', function() {
    let setPosition = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setPosition
      }
    });
    component.onProgress(options.playerState.played);
    assert.isFalse(setPosition.called);
  });

  it('check onProgress for loaded', function() {
    let setBuffered = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setBuffered
      }
    });
    component.onProgress({loaded: 200});
    assert.isTrue(setBuffered.calledOnce);
  });

  it('check onProgress for the same loaded', function() {
    let setBuffered = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setBuffered
      }
    });
    component.onProgress(options.playerState.loaded);
    assert.isFalse(setBuffered.called);
  });

  it('check onSeekMouseDown', function() {
    component.calcPosition = function () {
      return 100;
    };
    component.onSeekMouseDown();
    assert.equal(component.state.seeking, true);
    assert.equal(component.state.seekValue, 100);
  });

  it('check onSeekMouseMove with seeking == false', function() {
    component.state.seeking = false;
    component.onSeekMouseMove();
    assert.equal(component.onSeekMouseMove(), false);
  });

  it('check onSeekMouseDown', function() {
    component.calcPosition = function () {
      return 100;
    };
    component.state.seeking = true;
    component.onSeekMouseMove();
    assert.equal(component.state.seekValue, 100);
  });

  it('check onSeekMouseUp', function() {
    component.calcPosition = function () {
      return 100;
    };
    component.state.seeking = true;
    component.seekOnPosition = sinon.spy();
    component.onSeekMouseUp();
    assert.equal(component.state.seeking, false);
    assert.equal(component.seekOnPosition.calledOnce, true);
  });

  it('check onVolumeChange', function() {
    component.onVolumeChange(50);
    assert.equal(component.state.volume, 50);
  });

  it('check fullscreenPlayer', function() {
    let setFullscreen = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setFullscreen
      }
    });
    component.fullscreenPlayer();
    assert.isTrue(setFullscreen.calledOnce);
  });

  it('check exitFullscreen', function() {
    let setFullscreen = sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setFullscreen
      }
    });
    component.exitFullscreen();
    assert.isTrue(setFullscreen.calledOnce);
  });

  it('check calcTimeOffset', function() {
    let res = component.calcTimeOffset(100);
    assert.equal(res, 0);
  });

  it('check calcTimeOffset without duration', function() {
    component = getComponent({
      ...options,
      mediaState: {
        ...options.mediaState,
        data: {
          metadata: {
            duration: null
          }
        }
      }
    });
    let res = component.calcTimeOffset(100);
    assert.equal(res, 0);
  });

  it('check calcPosition', function() {
    let res = component.calcPosition({
      pageX: 1000,
      currentTarget: {
        clientWidth: 1000
      }
    });
    assert.equal(res, 1);
  });

  it('check seekToFirstMarker', function() {
    var clock = sinon.useFakeTimers();
    let clearJustCreatedMarkers= sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        clearJustCreatedMarkers
      }
    });
    component.onSeekMarker = sinon.spy();
    component.seekToFirstMarker(options.markersState);
    clock.tick(200);

    assert.equal(clearJustCreatedMarkers.calledOnce, true);
    assert.equal(component.onSeekMarker.calledOnce, true);
    clock.restore();
  });

  it('check seekToNextMarker from last markers', function() {
    component = getComponent({
      ...options,
      playerState: {
        ...options.playerState,
        played: 100
      }
    });
    component.seekOnPosition = sinon.spy();
    component.onSeekMarker = sinon.spy();
    component.seekToNextMarker();

    assert.equal(component.onSeekMarker.calledOnce, true);
    assert.equal(component.seekOnPosition.called, false);
  });

  it('check seekToNextMarker from non-last markers', function() {
    component = getComponent({
      ...options,
      playerState: {
        ...options.playerState,
        duration: 100
      }
    });

    component.seekOnPosition = sinon.spy();
    component.onSeekMarker = sinon.spy();
    component.seekToNextMarker();

    assert.equal(component.onSeekMarker.called, false);
    assert.equal(component.seekOnPosition.calledOnce, true);
  });

  it('check seekToUtterance', function() {
    var clock = sinon.useFakeTimers();
    let clearUtteranceTime= sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        clearUtteranceTime
      }
    });
    component.onSeekMarker = sinon.spy();
    component.seekToUtterance(100);
    clock.tick(100);

    assert.equal(clearUtteranceTime.calledOnce, true);
    assert.equal(component.onSeekMarker.calledOnce, true);
    clock.restore();
  });

  it('check seekOnPosition', function() {
    let setPosition= sinon.spy();
    component = getComponent({
      ...options,
      actions: {
        ...options.actions,
        setPosition
      }
    });
    component.seekOnPosition(100);

    assert.equal(setPosition.calledOnce, true);
  });

  it('check onSeekMarker', function() {
    component.seekOnPosition = sinon.spy();
    component.onSeekMarker();
    assert.equal(component.seekOnPosition.calledOnce, true);
  });

});

<|endoftext|>


<commit_before>import should from 'should';
import { transformString } from '../src/transform';

function test(input, output) {
  it(input, () => should(transformString(input)).equal(output));
}

describe('transform', () => {
  it('should turn a string into a string',
    () => transformString("()").should.be.a.String());

  describe('variables', () => {
    test('(let a 2)', 'var a = 2;');
    test('(let a 2 b 4 c 5)', 'var a = 2;var b = 4;var c = 5;');
    test('(let a (+ 1 2))', 'var a = (1 + 2);');
  });

  describe('math', () => {
    test('(+ 1 2)', '1 + 2');
    test('(- 9 6)', '9 - 6');
    test('(* 2 3)', '2 * 3');
    test('(/ 4 2)', '4 / 2');
    test('(* (+ 2 4) (- 5 3))', '(2 + 4) * (5 - 3)');
    test('(+ 2 3 4 5)', '2 + 3 + 4 + 5');

    test('(Math.pow 2 4)', 'Math.pow(2, 4)');
    test('(Math.abs -4)', 'Math.abs(-4)');
    test('(Math.pow (* 2 3) (- 2 4))', 'Math.pow((2 * 3), (2 - 4))');
  });

  describe('control flow', () => {
    describe('if else', () => {});
    describe('for loops', () => {});
    describe('while loops', () => {});
  });

  describe('function literals', () => {
    test('(function ())', 'function () {return null;}');
    test('(function () 4)', '(function () { return 4;})');
    test('(function (x y) (+ x y))', '(function (x, y) { return (x + y);})');
    test('(function adder (x y) (+ x y))', '(function adder(x, y) { return (x + y);})');
    test('(function (x) (function (y) (+ x y)))', '(function (x) { return (function (y) { return (x + y);});})');
  });

  describe('function calls', () => {
    test('(some_func 1 2 3)', 'some_func(1, 2, 3)');
    test('(func 1 (nested 2 3))', 'func(1, nested(2, 3))');
    test('(empty_func)', 'empty_func()');
  });

  describe('data structures', () => {
    describe('arrays', () => {});
    describe('objects', () => {});
  });

  describe.only('modules', () => {
    test(`
      (module testEm
        (+ 1 2))
      `,
      `module('testEm', function (require, export) {1 + 2;})`);
    test(`
      (module testEm
        (export varA (+ 1 2)))
      `,
      `module('testEm', function (require, export) {export('varA', (1 + 2));})`);
    test(`
      (module testEmA
        (require testEmB (varA)))
      `,
      `module('testEmA', function (require, export) {
         var testEmB = require('testEmB');
         var varA = testEmB['varA'];
       })`);
    test(`
      (module testEmA
        (require testEmB
          (varA
           varB
           varC)))
      `,
      `module('testEmA', function (require, export) {
         var testEmB = require('testEmB');
         var varA = testEmB['varA'];
         var varB = testEmB['varB'];
         var varC = testEmB['varC'];
       })`);
  });

  describe('calling methods on dynamic entities', () => {});
});
<commit_msg>it's gross, but it's better have no whitespace in the expeted results right now than to mess around with a whitespace cleaner that could invalidate results<commit_after>import should from 'should';
import { transformString } from '../src/transform';

function test(input, output) {
  it(input, () => should(transformString(input)).equal(output));
}

describe('transform', () => {
  it('should turn a string into a string',
    () => transformString("()").should.be.a.String());

  describe('variables', () => {
    test('(let a 2)', 'var a = 2;');
    test('(let a 2 b 4 c 5)', 'var a = 2;var b = 4;var c = 5;');
    test('(let a (+ 1 2))', 'var a = (1 + 2);');
  });

  describe('math', () => {
    test('(+ 1 2)', '1 + 2');
    test('(- 9 6)', '9 - 6');
    test('(* 2 3)', '2 * 3');
    test('(/ 4 2)', '4 / 2');
    test('(* (+ 2 4) (- 5 3))', '(2 + 4) * (5 - 3)');
    test('(+ 2 3 4 5)', '2 + 3 + 4 + 5');

    test('(Math.pow 2 4)', 'Math.pow(2, 4)');
    test('(Math.abs -4)', 'Math.abs(-4)');
    test('(Math.pow (* 2 3) (- 2 4))', 'Math.pow((2 * 3), (2 - 4))');
  });

  describe('control flow', () => {
    describe('if else', () => {});
    describe('for loops', () => {});
    describe('while loops', () => {});
  });

  describe('function literals', () => {
    test('(function ())', 'function () {return null;}');
    test('(function () 4)', '(function () { return 4;})');
    test('(function (x y) (+ x y))', '(function (x, y) { return (x + y);})');
    test('(function adder (x y) (+ x y))', '(function adder(x, y) { return (x + y);})');
    test('(function (x) (function (y) (+ x y)))', '(function (x) { return (function (y) { return (x + y);});})');
  });

  describe('function calls', () => {
    test('(some_func 1 2 3)', 'some_func(1, 2, 3)');
    test('(func 1 (nested 2 3))', 'func(1, nested(2, 3))');
    test('(empty_func)', 'empty_func()');
  });

  describe('data structures', () => {
    describe('arrays', () => {});
    describe('objects', () => {});
  });

  describe('modules', () => {
    test(`
      (module testEm
        (+ 1 2))
      `,
      `module('testEm', function (require, export) {1 + 2;})`);
    test(`
      (module testEm
        (export varA (+ 1 2)))
      `,
      `module('testEm', function (require, export) {export('varA', (1 + 2));})`);
    test(`
      (module testEmA
        (require testEmB (varA)))
      `,
      `module('testEmA', function (require, export) {var testEmB = require('testEmB');var varA = testEmB['varA'];})`);
    test(`
      (module testEmA
        (require testEmB
          (varA
           varB
           varC)))
      `,
      `module('testEmA', function (require, export) {var testEmB = require('testEmB');var varA = testEmB['varA'];var varB = testEmB['varB'];var varC = testEmB['varC'];})`);
  });

  describe('calling methods on dynamic entities', () => {});
});
<|endoftext|>


<commit_before>// 排除源码目录下的node_modules目录，不对其进行构建
fis.config.set('project.exclude', 'node_modules/**');

// 利用package.json文件定义项目名和版本
var meta = require('./package.json');
fis.config.set('name', meta.name);
fis.config.set('version', meta.version);

// 对md、tpl后缀的文件指定用fis-optimizer-html-minifier插件进行压缩
fis.config.set('modules.optimizer.md', 'html-minifier');
fis.config.set('modules.optimizer.tpl', 'html-minifier');

// scrat.js框架开启localstorage缓存
fis.config.set('framework.cache', true);
// 静态资源加载路径模式
fis.config.set('framework.urlPattern', '/public/c/%s');

//设置url前缀
fis.config.set('urlPrefix', '/babyshop/public');

// fis-lint-jshint插件配置
fis.config.set('settings.lint.jshint', {
    // 在jshint基础上加上了i18n配置，将报错信息翻译成中文
    i18n: 'zh-CN',
    // 在jshint基础上加上了ignored配置，排除框架文件、第三方模块
    ignored: [
        'views/lib/**',
        'component_modules/**'
    ],
    // 其他配置项请直接参阅jshint官网说明
    predef: [
        'define',
        'Handlebars',
        '__FRAMEWORK_CONFIG__',
        'ga'
    ],
    bitwise: true,
    camelcase: true,
    eqeqeq: true,
    forin: true,
    immed: true,
    indent: 4,
    newcap: true,
    noarg: true,
    noempty: true,
    nonew: true,
    undef: true,
    strict: true,
    boss: true,
    trailing: true,
    eqnull: true,
    browser: true,
    devel: true,
    jquery: true,
    node: true,
    white: false
});

// 使用pngquant把png图片压缩为png8，减少质量
fis.config.set('settings.optimizer.png-compressor.type', 'pngquant');

// markdown的标题id前缀
fis.config.set('settings.parser.marked.headerPrefix', 'user-content-');

// fis-optimizer-html-minifier插件配置
fis.config.set('settings.optimizer.html-minifier', {
    // fis直接将此配置传递给html-minfier模块
    // 因此相关配置项请直接参阅html-minifier文档
    removeComments: true,
    collapseWhitespace: true,
    conservativeCollapse: true,
    removeAttributeQuotes: true
});<commit_msg>[UPD] 修改配置静态资源路径<commit_after>// 排除源码目录下的node_modules目录，不对其进行构建
fis.config.set('project.exclude', 'node_modules/**');

// 利用package.json文件定义项目名和版本
var meta = require('./package.json');
fis.config.set('name', meta.name);
fis.config.set('version', meta.version);

// 对md、tpl后缀的文件指定用fis-optimizer-html-minifier插件进行压缩
fis.config.set('modules.optimizer.md', 'html-minifier');
fis.config.set('modules.optimizer.tpl', 'html-minifier');

// scrat.js框架开启localstorage缓存
fis.config.set('framework.cache', true);
// 静态资源加载路径模式
fis.config.set('framework.urlPattern', '/babyshop/public/c/%s');

//设置url前缀
fis.config.set('urlPrefix', '/babyshop/public');

// fis-lint-jshint插件配置
fis.config.set('settings.lint.jshint', {
    // 在jshint基础上加上了i18n配置，将报错信息翻译成中文
    i18n: 'zh-CN',
    // 在jshint基础上加上了ignored配置，排除框架文件、第三方模块
    ignored: [
        'views/lib/**',
        'component_modules/**'
    ],
    // 其他配置项请直接参阅jshint官网说明
    predef: [
        'define',
        'Handlebars',
        '__FRAMEWORK_CONFIG__',
        'ga'
    ],
    bitwise: true,
    camelcase: true,
    eqeqeq: true,
    forin: true,
    immed: true,
    indent: 4,
    newcap: true,
    noarg: true,
    noempty: true,
    nonew: true,
    undef: true,
    strict: true,
    boss: true,
    trailing: true,
    eqnull: true,
    browser: true,
    devel: true,
    jquery: true,
    node: true,
    white: false
});

// 使用pngquant把png图片压缩为png8，减少质量
fis.config.set('settings.optimizer.png-compressor.type', 'pngquant');

// markdown的标题id前缀
fis.config.set('settings.parser.marked.headerPrefix', 'user-content-');

// fis-optimizer-html-minifier插件配置
fis.config.set('settings.optimizer.html-minifier', {
    // fis直接将此配置传递给html-minfier模块
    // 因此相关配置项请直接参阅html-minifier文档
    removeComments: true,
    collapseWhitespace: true,
    conservativeCollapse: true,
    removeAttributeQuotes: true
});<|endoftext|>


<commit_before>/**
 * This code is mostly from the old Etherpad. Please help us to comment this code.
 * This helps other people to understand this code better and helps them to improve it.
 * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
 */

/**
 * Copyright 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// requires: top
// requires: plugins
// requires: undefined

var KERNEL_SOURCE = '../static/js/require-kernel.js';

Ace2Editor.registry = {
  nextId: 1
};

var hooks = require('./pluginfw/hooks');
var _ = require('./underscore');

function scriptTag(source) {
  return (
    ''
  )
}

function Ace2Editor()
{
  var ace2 = Ace2Editor;

  var editor = {};
  var info = {
    editor: editor,
    id: (ace2.registry.nextId++)
  };
  var loaded = false;

  var actionsPendingInit = [];

  function pendingInit(func, optDoNow)
  {
    return function()
    {
      var that = this;
      var args = arguments;
      var action = function()
      {
        func.apply(that, args);
      }
      if (optDoNow)
      {
        optDoNow.apply(that, args);
      }
      if (loaded)
      {
        action();
      }
      else
      {
        actionsPendingInit.push(action);
      }
    };
  }

  function doActionsPendingInit()
  {
    _.each(actionsPendingInit, function(fn,i){
      fn()
    });
    actionsPendingInit = [];
  }

  ace2.registry[info.id] = info;

  // The following functions (prefixed by 'ace_')  are exposed by editor, but
  // execution is delayed until init is complete
  var aceFunctionsPendingInit = ['importText', 'importAText', 'focus',
  'setEditable', 'getFormattedCode', 'setOnKeyPress', 'setOnKeyDown',
  'setNotifyDirty', 'setProperty', 'setBaseText', 'setBaseAttributedText',
  'applyChangesToBase', 'applyPreparedChangesetToBase',
  'setUserChangeNotificationCallback', 'setAuthorInfo',
  'setAuthorSelectionRange', 'callWithAce', 'execCommand', 'replaceRange'];

  _.each(aceFunctionsPendingInit, function(fnName,i){
    var prefix = 'ace_';
    var name = prefix + fnName;
    editor[fnName] = pendingInit(function(){
      info[prefix + fnName].apply(this, arguments);
    });
  });

  editor.exportText = function()
  {
    if (!loaded) return "(awaiting init)\n";
    return info.ace_exportText();
  };

  editor.getFrame = function()
  {
    return info.frame || null;
  };

  editor.getDebugProperty = function(prop)
  {
    return info.ace_getDebugProperty(prop);
  };

  editor.getInInternationalComposition = function()
  {
    if (!loaded) return false;
    return info.ace_getInInternationalComposition();
  };

  // prepareUserChangeset:
  // Returns null if no new changes or ACE not ready.  Otherwise, bundles up all user changes
  // to the latest base text into a Changeset, which is returned (as a string if encodeAsString).
  // If this method returns a truthy value, then applyPreparedChangesetToBase can be called
  // at some later point to consider these changes part of the base, after which prepareUserChangeset
  // must be called again before applyPreparedChangesetToBase.  Multiple consecutive calls
  // to prepareUserChangeset will return an updated changeset that takes into account the
  // latest user changes, and modify the changeset to be applied by applyPreparedChangesetToBase
  // accordingly.
  editor.prepareUserChangeset = function()
  {
    if (!loaded) return null;
    return info.ace_prepareUserChangeset();
  };

  editor.getUnhandledErrors = function()
  {
    if (!loaded) return [];
    // returns array of {error: <browser Error object>, time: +new Date()}
    return info.ace_getUnhandledErrors();
  };

  function sortFilesByEmbeded(files) {
    var embededFiles = [];
    var remoteFiles = [];

    if (Ace2Editor.EMBEDED) {
      for (var i = 0, ii = files.length; i < ii; i++) {
        var file = files[i];
        if (Object.prototype.hasOwnProperty.call(Ace2Editor.EMBEDED, file)) {
          embededFiles.push(file);
        } else {
          remoteFiles.push(file);
        }
      }
    } else {
      remoteFiles = files;
    }

    return {embeded: embededFiles, remote: remoteFiles};
  }
  function pushStyleTagsFor(buffer, files) {
    var sorted = sortFilesByEmbeded(files);
    var embededFiles = sorted.embeded;
    var remoteFiles = sorted.remote;

    if (embededFiles.length > 0) {
      buffer.push('');

      hooks.callAll("aceInitInnerdocbodyHead", {
        iframeHTML: iframeHTML
      });

      iframeHTML.push(' ');

      // Expose myself to global for my child frame.
      var thisFunctionsName = "ChildAccessibleAce2Editor";
      (function () {return this}())[thisFunctionsName] = Ace2Editor;

      var outerScript = '\
editorId = ' + JSON.stringify(info.id) + ';\n\
editorInfo = parent[' + JSON.stringify(thisFunctionsName) + '].registry[editorId];\n\
window.onload = function () {\n\
  window.onload = null;\n\
  setTimeout(function () {\n\
    var iframe = document.createElement("IFRAME");\n\
    iframe.name = "ace_inner";\n\
    iframe.title = "pad";\n\
    iframe.scrolling = "no";\n\
    var outerdocbody = document.getElementById("outerdocbody");\n\
    iframe.frameBorder = 0;\n\
    iframe.allowTransparency = true; // for IE\n\
    outerdocbody.insertBefore(iframe, outerdocbody.firstChild);\n\
    iframe.ace_outerWin = window;\n\
    readyFunc = function () {\n\
      editorInfo.onEditorReady();\n\
      readyFunc = null;\n\
      editorInfo = null;\n\
    };\n\
    var doc = iframe.contentWindow.document;\n\
    doc.open();\n\
    var text = (' + JSON.stringify(iframeHTML.join('\n')) + ');\n\
    doc.write(text);\n\
    doc.close();\n\
  }, 0);\n\
}';

      var outerHTML = [doctype, '']

      var includedCSS = [];
      var $$INCLUDE_CSS = function(filename) {includedCSS.push(filename)};
      $$INCLUDE_CSS("../static/css/iframe_editor.css");
      $$INCLUDE_CSS("../static/css/pad.css");
      $$INCLUDE_CSS("../static/custom/pad.css");

      var additionalCSS = _(hooks.callAll("aceEditorCSS")).map(function(path){
        if (path.match(/\/\//)) { // Allow urls to external CSS - http(s):// and //some/path.css
          return path;
        }
        return '../static/plugins/' + path }
      );
      includedCSS = includedCSS.concat(additionalCSS);

      pushStyleTagsFor(outerHTML, includedCSS);

      // bizarrely, in FF2, a file with no "external" dependencies won't finish loading properly
      // (throbs busy while typing)
      outerHTML.push('', '<link rel="stylesheet" type="text/css" href="data:text/css,"/>', scriptTag(outerScript), '

x
');

      var outerFrame = document.createElement("IFRAME");
      outerFrame.name = "ace_outer";
      outerFrame.frameBorder = 0; // for IE
      outerFrame.title = "Ether";
      info.frame = outerFrame;
      document.getElementById(containerId).appendChild(outerFrame);

      var editorDocument = outerFrame.contentWindow.document;

      editorDocument.open();
      editorDocument.write(outerHTML.join(''));
      editorDocument.close();
    })();
  };

  return editor;
}

exports.Ace2Editor = Ace2Editor;
<commit_msg>ace.js: use URL encoding when building an URL via string concatenation<commit_after>/**
 * This code is mostly from the old Etherpad. Please help us to comment this code.
 * This helps other people to understand this code better and helps them to improve it.
 * TL;DR COMMENTS ON THIS FILE ARE HIGHLY APPRECIATED
 */

/**
 * Copyright 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// requires: top
// requires: plugins
// requires: undefined

var KERNEL_SOURCE = '../static/js/require-kernel.js';

Ace2Editor.registry = {
  nextId: 1
};

var hooks = require('./pluginfw/hooks');
var _ = require('./underscore');

function scriptTag(source) {
  return (
    ''
  )
}

function Ace2Editor()
{
  var ace2 = Ace2Editor;

  var editor = {};
  var info = {
    editor: editor,
    id: (ace2.registry.nextId++)
  };
  var loaded = false;

  var actionsPendingInit = [];

  function pendingInit(func, optDoNow)
  {
    return function()
    {
      var that = this;
      var args = arguments;
      var action = function()
      {
        func.apply(that, args);
      }
      if (optDoNow)
      {
        optDoNow.apply(that, args);
      }
      if (loaded)
      {
        action();
      }
      else
      {
        actionsPendingInit.push(action);
      }
    };
  }

  function doActionsPendingInit()
  {
    _.each(actionsPendingInit, function(fn,i){
      fn()
    });
    actionsPendingInit = [];
  }

  ace2.registry[info.id] = info;

  // The following functions (prefixed by 'ace_')  are exposed by editor, but
  // execution is delayed until init is complete
  var aceFunctionsPendingInit = ['importText', 'importAText', 'focus',
  'setEditable', 'getFormattedCode', 'setOnKeyPress', 'setOnKeyDown',
  'setNotifyDirty', 'setProperty', 'setBaseText', 'setBaseAttributedText',
  'applyChangesToBase', 'applyPreparedChangesetToBase',
  'setUserChangeNotificationCallback', 'setAuthorInfo',
  'setAuthorSelectionRange', 'callWithAce', 'execCommand', 'replaceRange'];

  _.each(aceFunctionsPendingInit, function(fnName,i){
    var prefix = 'ace_';
    var name = prefix + fnName;
    editor[fnName] = pendingInit(function(){
      info[prefix + fnName].apply(this, arguments);
    });
  });

  editor.exportText = function()
  {
    if (!loaded) return "(awaiting init)\n";
    return info.ace_exportText();
  };

  editor.getFrame = function()
  {
    return info.frame || null;
  };

  editor.getDebugProperty = function(prop)
  {
    return info.ace_getDebugProperty(prop);
  };

  editor.getInInternationalComposition = function()
  {
    if (!loaded) return false;
    return info.ace_getInInternationalComposition();
  };

  // prepareUserChangeset:
  // Returns null if no new changes or ACE not ready.  Otherwise, bundles up all user changes
  // to the latest base text into a Changeset, which is returned (as a string if encodeAsString).
  // If this method returns a truthy value, then applyPreparedChangesetToBase can be called
  // at some later point to consider these changes part of the base, after which prepareUserChangeset
  // must be called again before applyPreparedChangesetToBase.  Multiple consecutive calls
  // to prepareUserChangeset will return an updated changeset that takes into account the
  // latest user changes, and modify the changeset to be applied by applyPreparedChangesetToBase
  // accordingly.
  editor.prepareUserChangeset = function()
  {
    if (!loaded) return null;
    return info.ace_prepareUserChangeset();
  };

  editor.getUnhandledErrors = function()
  {
    if (!loaded) return [];
    // returns array of {error: <browser Error object>, time: +new Date()}
    return info.ace_getUnhandledErrors();
  };

  function sortFilesByEmbeded(files) {
    var embededFiles = [];
    var remoteFiles = [];

    if (Ace2Editor.EMBEDED) {
      for (var i = 0, ii = files.length; i < ii; i++) {
        var file = files[i];
        if (Object.prototype.hasOwnProperty.call(Ace2Editor.EMBEDED, file)) {
          embededFiles.push(file);
        } else {
          remoteFiles.push(file);
        }
      }
    } else {
      remoteFiles = files;
    }

    return {embeded: embededFiles, remote: remoteFiles};
  }
  function pushStyleTagsFor(buffer, files) {
    var sorted = sortFilesByEmbeded(files);
    var embededFiles = sorted.embeded;
    var remoteFiles = sorted.remote;

    if (embededFiles.length > 0) {
      buffer.push('');

      hooks.callAll("aceInitInnerdocbodyHead", {
        iframeHTML: iframeHTML
      });

      iframeHTML.push(' ');

      // Expose myself to global for my child frame.
      var thisFunctionsName = "ChildAccessibleAce2Editor";
      (function () {return this}())[thisFunctionsName] = Ace2Editor;

      var outerScript = '\
editorId = ' + JSON.stringify(info.id) + ';\n\
editorInfo = parent[' + JSON.stringify(thisFunctionsName) + '].registry[editorId];\n\
window.onload = function () {\n\
  window.onload = null;\n\
  setTimeout(function () {\n\
    var iframe = document.createElement("IFRAME");\n\
    iframe.name = "ace_inner";\n\
    iframe.title = "pad";\n\
    iframe.scrolling = "no";\n\
    var outerdocbody = document.getElementById("outerdocbody");\n\
    iframe.frameBorder = 0;\n\
    iframe.allowTransparency = true; // for IE\n\
    outerdocbody.insertBefore(iframe, outerdocbody.firstChild);\n\
    iframe.ace_outerWin = window;\n\
    readyFunc = function () {\n\
      editorInfo.onEditorReady();\n\
      readyFunc = null;\n\
      editorInfo = null;\n\
    };\n\
    var doc = iframe.contentWindow.document;\n\
    doc.open();\n\
    var text = (' + JSON.stringify(iframeHTML.join('\n')) + ');\n\
    doc.write(text);\n\
    doc.close();\n\
  }, 0);\n\
}';

      var outerHTML = [doctype, '']

      var includedCSS = [];
      var $$INCLUDE_CSS = function(filename) {includedCSS.push(filename)};
      $$INCLUDE_CSS("../static/css/iframe_editor.css");
      $$INCLUDE_CSS("../static/css/pad.css");
      $$INCLUDE_CSS("../static/custom/pad.css");

      var additionalCSS = _(hooks.callAll("aceEditorCSS")).map(function(path){
        if (path.match(/\/\//)) { // Allow urls to external CSS - http(s):// and //some/path.css
          return path;
        }
        return '../static/plugins/' + path }
      );
      includedCSS = includedCSS.concat(additionalCSS);

      pushStyleTagsFor(outerHTML, includedCSS);

      // bizarrely, in FF2, a file with no "external" dependencies won't finish loading properly
      // (throbs busy while typing)
      outerHTML.push('', '<link rel="stylesheet" type="text/css" href="data:text/css,"/>', scriptTag(outerScript), '

x
');

      var outerFrame = document.createElement("IFRAME");
      outerFrame.name = "ace_outer";
      outerFrame.frameBorder = 0; // for IE
      outerFrame.title = "Ether";
      info.frame = outerFrame;
      document.getElementById(containerId).appendChild(outerFrame);

      var editorDocument = outerFrame.contentWindow.document;

      editorDocument.open();
      editorDocument.write(outerHTML.join(''));
      editorDocument.close();
    })();
  };

  return editor;
}

exports.Ace2Editor = Ace2Editor;
<|endoftext|>


<commit_before>var context,
    audioBuffer,
    sourceNode,
    analyser,
    javascriptNode,
    ctx,
    tempCanvas,
    tempCtx,
    hot,
    array,
    canvas,
    value,
    i;

// log if an error occurs
function onError(e) {
    "use strict";
    console.log(e);
}

function drawSpectrogram(array) {
    "use strict";
    // copy the current canvas onto the temp canvas
    canvas = document.getElementById("canvas");

    tempCtx.drawImage(canvas, 0, 0, 800, 512);

    // iterate over the elements from the array
    for (i = 0; i < array.length; i += 1) {
        // draw each pixel with the specific color
        value = array[i];
        ctx.fillStyle = hot.getColor(value).hex();

        // draw the line at the right side of the canvas
        ctx.fillRect(800 - 1, 512 - i, 1, 1);
    }

    // set translate on the canvas
    ctx.translate(-1, 0);
    // draw the copied image
    ctx.drawImage(tempCanvas, 0, 0, 800, 512, 0, 0, 800, 512);

    // reset the transformation matrix
    ctx.setTransform(1, 0, 0, 1, 0, 0);

}

function setupAudioNodes() {
    "use strict";
    // setup a javascript node
    javascriptNode = context.createScriptProcessor(2048, 1, 1);
    // connect to destination, else it isn't called
    javascriptNode.connect(context.destination);

    // setup a analyzer
    analyser = context.createAnalyser();
    analyser.smoothingTimeConstant = 0;
    analyser.fftSize = 1024;

    // create a buffer source node
    //sourceNode = context.createBufferSource();
    gainNode.connect(analyser);
    analyser.connect(javascriptNode);

   // sourceNode.connect(context.destination);
}

function audioProcess() {
    "use strict";
    // get the average for the first channel
    array = new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(array);

    // draw the spectrogram
    if (!source.mediaElement.paused) {
        //console.log(document.getElementById("src1").paused);
        drawSpectrogram(array);
    }
}

context = audioCtx;
// get the context from the canvas to draw on
ctx = $("#canvas").get()[0].getContext("2d");

// create a temp canvas we use for copying
tempCanvas = document.createElement("canvas");
tempCtx = tempCanvas.getContext("2d");
tempCanvas.width = 800;
tempCanvas.height = 512;

    // used for color distribution
hot = new chroma.ColorScale({
    colors: ['#000000', '#ff0000', '#ffff00', '#ffffff'],
    positions: [0, 0.25, 0.75, 1],
    mode: 'rgb',
    limits: [0, 300]
});

// load the sound
setupAudioNodes();

// when the javascript node is called
// we use information from the analyzer node
// to draw the volume
javascriptNode.onaudioprocess = audioProcess();<commit_msg>Fixed Bug in onaudioprocess function call<commit_after>var context,
    audioBuffer,
    sourceNode,
    analyser,
    javascriptNode,
    ctx,
    tempCanvas,
    tempCtx,
    hot,
    array,
    canvas,
    value,
    i;

// log if an error occurs
function onError(e) {
    "use strict";
    console.log(e);
}

function drawSpectrogram(array) {
    "use strict";
    // copy the current canvas onto the temp canvas
    canvas = document.getElementById("canvas");

    tempCtx.drawImage(canvas, 0, 0, 800, 512);

    // iterate over the elements from the array
    for (i = 0; i < array.length; i += 1) {
        // draw each pixel with the specific color
        value = array[i];
        ctx.fillStyle = hot.getColor(value).hex();

        // draw the line at the right side of the canvas
        ctx.fillRect(800 - 1, 512 - i, 1, 1);
    }

    // set translate on the canvas
    ctx.translate(-1, 0);
    // draw the copied image
    ctx.drawImage(tempCanvas, 0, 0, 800, 512, 0, 0, 800, 512);

    // reset the transformation matrix
    ctx.setTransform(1, 0, 0, 1, 0, 0);

}

function setupAudioNodes() {
    "use strict";
    // setup a javascript node
    javascriptNode = context.createScriptProcessor(2048, 1, 1);
    // connect to destination, else it isn't called
    javascriptNode.connect(context.destination);

    // setup a analyzer
    analyser = context.createAnalyser();
    analyser.smoothingTimeConstant = 0;
    analyser.fftSize = 1024;

    // create a buffer source node
    //sourceNode = context.createBufferSource();
    gainNode.connect(analyser);
    analyser.connect(javascriptNode);

   // sourceNode.connect(context.destination);
}

function audioProcess() {
    "use strict";
    // get the average for the first channel
    array = new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(array);

    // draw the spectrogram
    if (!source.mediaElement.paused) {
        //console.log(document.getElementById("src1").paused);
        drawSpectrogram(array);
    }
}

context = audioCtx;
// get the context from the canvas to draw on
ctx = $("#canvas").get()[0].getContext("2d");

// create a temp canvas we use for copying
tempCanvas = document.createElement("canvas");
tempCtx = tempCanvas.getContext("2d");
tempCanvas.width = 800;
tempCanvas.height = 512;

    // used for color distribution
hot = new chroma.ColorScale({
    colors: ['#000000', '#ff0000', '#ffff00', '#ffffff'],
    positions: [0, 0.25, 0.75, 1],
    mode: 'rgb',
    limits: [0, 300]
});

// load the sound
setupAudioNodes();

// when the javascript node is called
// we use information from the analyzer node
// to draw the volume
javascriptNode.onaudioprocess = audioProcess;<|endoftext|>


<commit_before>/**
 * WordPress dependencies
 */
import { createNewPost, saveDraft, clickButton, selectBlockByClientId, getAllBlocks } from '@wordpress/e2e-test-utils';

/**
 * Internal dependencies
 */
import {
	activateExperience,
	deactivateExperience,
	clickButtonByLabel,
	getSidebarPanelToggleByTitle,
	uploadMedia,
	openPreviewPage,
	insertBlock,
} from '../../utils';

describe( 'Story Page', () => {
	beforeAll( async () => {
		await activateExperience( 'stories' );
	} );

	afterAll( async () => {
		await deactivateExperience( 'stories' );
	} );

	beforeEach( async () => {
		await createNewPost( { postType: 'amp_story' } );
		// Select the default page block.
		await selectBlockByClientId(
			( await getAllBlocks() )[ 0 ].clientId
		);
	} );

	it( 'should be possible to add background color to Page', async () => {
		const panelTitle = 'Background Color';
		const colorToggle = await getSidebarPanelToggleByTitle( panelTitle );

		await colorToggle.click();

		await clickButtonByLabel( 'Color: Vivid red' );

		await saveDraft();
		await page.reload();

		const style = 'background-color: rgb(207, 46, 46); opacity: 1;';

		const nodes = await page.$x(
			`//div[contains(@class, "amp-page-active")]//div[contains(@style,"${ style }")]`
		);
		expect( nodes.length ).not.toStrictEqual( 0 );
	} );

	it( 'should allow adding gradient', async () => {
		const panelTitle = 'Background Color';
		const colorToggle = await getSidebarPanelToggleByTitle( panelTitle );

		await colorToggle.click();
		await clickButtonByLabel( 'Color: Vivid red' );
		await clickButton( 'Add Gradient' );

		await saveDraft();
		await page.reload();

		const style = 'background-image: linear-gradient(rgb(207, 46, 46), transparent)';

		const nodes = await page.$x(
			`//div[contains(@class, "amp-page-active")]//div[contains(@style,"${ style }")]`
		);
		expect( nodes.length ).not.toStrictEqual( 0 );
	} );

	it( 'should allow adding opacity', async () => {
		const panelTitle = 'Background Color';
		const colorToggle = await getSidebarPanelToggleByTitle( panelTitle );

		await colorToggle.click();
		const opacitySelector = '.components-range-control__number[aria-label="Opacity"]';
		await page.waitForSelector( opacitySelector );

		// Set opacity to 15.
		await page.evaluate( () => {
			document.querySelector( '.components-range-control__number[aria-label="Opacity"]' ).value = '';
		} );

		await page.type( opacitySelector, '15' );

		await clickButtonByLabel( 'Color: Vivid red' );

		await saveDraft();
		await page.reload();

		const style = 'opacity: 0.15;';
		const nodes = await page.$x(
			`//div[contains(@class, "amp-page-active")]//div[contains(@style,"${ style }")]`
		);
		expect( nodes.length ).not.toStrictEqual( 0 );
	} );

	it( 'should be possible to add Background Image', async () => {
		// Click the media selection button.
		await page.waitForSelector( '.editor-amp-story-page-background' );
		await page.click( '.editor-amp-story-page-background' );
		await uploadMedia( 'large-image-36521.jpg' );

		// Insert the image.
		await page.click( '.media-modal button.media-button-select' );

		// Wait for media to be inserted.
		await page.waitForSelector( '.components-focal-point-picker-wrapper' );
		await saveDraft();
		await page.reload();

		const editorPage = page;
		const previewPage = await openPreviewPage( editorPage, 'amp-story' );
		await previewPage.waitForSelector( '.amp-story-block-wrapper' );

		const [ elementHandle ] = await previewPage.$x( '//amp-story-page/amp-story-grid-layer/amp-img/@src' );
		const srcHandle = await elementHandle.getProperty( 'value' );
		const src = await srcHandle.jsonValue();
		expect( src ).toContain( '.jpg' );
		expect( src ).toContain( 'wp-content/uploads' );
	} );

	it( 'should save tha page advancement setting correctly', async () => {
		const pageAdvancementSelector = '.components-select-control__input';
		await page.waitForSelector( pageAdvancementSelector );
		await page.select( pageAdvancementSelector, 'time' );

		const secondsSelector = 'input[aria-label="Time in seconds"]';
		await page.waitForSelector( secondsSelector );
		await page.type( secondsSelector, '15' );

		await saveDraft();
		await page.reload();

		await selectBlockByClientId(
			( await getAllBlocks() )[ 0 ].clientId
		);
		await page.waitForSelector( secondsSelector );

		expect( await page.evaluate( ( selector ) => {
			return document.querySelector( selector ).value;
		}, secondsSelector ) ).toBe( '15' );

		const editorPage = page;
		const previewPage = await openPreviewPage( editorPage, 'amp-story' );
		await previewPage.waitForSelector( '.amp-story-block-wrapper' );

		const [ elementHandle ] = await previewPage.$x( '//amp-story-page/@auto-advance-after' );
		const secondsHandle = await elementHandle.getProperty( 'value' );
		const seconds = await secondsHandle.jsonValue();
		expect( seconds ).toStrictEqual( '15s' );
	} );

	it( 'should consider animations time when setting the page advancement', async () => {
		await insertBlock( 'Author' );

		const animationTypeSelector = '.is-opened select.components-select-control__input';
		await page.waitForSelector( animationTypeSelector );
		await page.select( animationTypeSelector, 'pulse' );

		const animationDelaySelector = 'input[aria-label="Delay (ms)"]';
		await page.waitForSelector( animationDelaySelector );
		await page.type( animationDelaySelector, '1500' );

		await selectBlockByClientId(
			( await getAllBlocks() )[ 0 ].clientId
		);

		const pageAdvancementSelector = '.components-select-control__input';
		await page.waitForSelector( pageAdvancementSelector );
		await page.select( pageAdvancementSelector, 'time' );

		const secondsSelector = 'input[aria-label="Time in seconds"]';
		await page.waitForSelector( secondsSelector );

		expect( await page.evaluate( ( selector ) => {
			return document.querySelector( selector ).value;
		}, secondsSelector ) ).toBe( '2' );
	} );
} );
<commit_msg>Change test after change to UX.<commit_after>/**
 * WordPress dependencies
 */
import { createNewPost, saveDraft, clickButton, selectBlockByClientId, getAllBlocks } from '@wordpress/e2e-test-utils';

/**
 * Internal dependencies
 */
import {
	activateExperience,
	deactivateExperience,
	clickButtonByLabel,
	getSidebarPanelToggleByTitle,
	uploadMedia,
	openPreviewPage,
	insertBlock,
} from '../../utils';

describe( 'Story Page', () => {
	beforeAll( async () => {
		await activateExperience( 'stories' );
	} );

	afterAll( async () => {
		await deactivateExperience( 'stories' );
	} );

	beforeEach( async () => {
		await createNewPost( { postType: 'amp_story' } );
		// Select the default page block.
		await selectBlockByClientId(
			( await getAllBlocks() )[ 0 ].clientId
		);
	} );

	it( 'should be possible to add background color to Page', async () => {
		await clickButtonByLabel( 'Color: Vivid red' );

		await saveDraft();
		await page.reload();

		const style = 'background-color: rgb(207, 46, 46); opacity: 1;';

		const nodes = await page.$x(
			`//div[contains(@class, "amp-page-active")]//div[contains(@style,"${ style }")]`
		);
		expect( nodes.length ).not.toStrictEqual( 0 );
	} );

	it( 'should allow adding gradient', async () => {
		await clickButtonByLabel( 'Color: Vivid red' );
		await clickButton( 'Add Gradient' );

		await saveDraft();
		await page.reload();

		const style = 'background-image: linear-gradient(rgb(207, 46, 46), transparent)';

		const nodes = await page.$x(
			`//div[contains(@class, "amp-page-active")]//div[contains(@style,"${ style }")]`
		);
		expect( nodes.length ).not.toStrictEqual( 0 );
	} );

	it( 'should allow adding opacity', async () => {
		const opacitySelector = '.components-range-control__number[aria-label="Opacity"]';
		await page.waitForSelector( opacitySelector );

		// Set opacity to 15.
		await page.evaluate( () => {
			document.querySelector( '.components-range-control__number[aria-label="Opacity"]' ).value = '';
		} );

		await page.type( opacitySelector, '15' );

		await clickButtonByLabel( 'Color: Vivid red' );

		await saveDraft();
		await page.reload();

		const style = 'opacity: 0.15;';
		const nodes = await page.$x(
			`//div[contains(@class, "amp-page-active")]//div[contains(@style,"${ style }")]`
		);
		expect( nodes.length ).not.toStrictEqual( 0 );
	} );

	it( 'should be possible to add Background Image', async () => {
		// Click the media selection button.
		await page.waitForSelector( '.editor-amp-story-page-background' );
		await page.click( '.editor-amp-story-page-background' );
		await uploadMedia( 'large-image-36521.jpg' );

		// Insert the image.
		await page.click( '.media-modal button.media-button-select' );

		// Wait for media to be inserted.
		await page.waitForSelector( '.components-focal-point-picker-wrapper' );
		await saveDraft();
		await page.reload();

		const editorPage = page;
		const previewPage = await openPreviewPage( editorPage, 'amp-story' );
		await previewPage.waitForSelector( '.amp-story-block-wrapper' );

		const [ elementHandle ] = await previewPage.$x( '//amp-story-page/amp-story-grid-layer/amp-img/@src' );
		const srcHandle = await elementHandle.getProperty( 'value' );
		const src = await srcHandle.jsonValue();
		expect( src ).toContain( '.jpg' );
		expect( src ).toContain( 'wp-content/uploads' );
	} );

	it( 'should save tha page advancement setting correctly', async () => {
		const pageAdvancementSelector = '.components-select-control__input';
		await page.waitForSelector( pageAdvancementSelector );
		await page.select( pageAdvancementSelector, 'time' );

		const secondsSelector = 'input[aria-label="Time in seconds"]';
		await page.waitForSelector( secondsSelector );
		await page.type( secondsSelector, '15' );

		await saveDraft();
		await page.reload();

		await selectBlockByClientId(
			( await getAllBlocks() )[ 0 ].clientId
		);
		await page.waitForSelector( secondsSelector );

		expect( await page.evaluate( ( selector ) => {
			return document.querySelector( selector ).value;
		}, secondsSelector ) ).toBe( '15' );

		const editorPage = page;
		const previewPage = await openPreviewPage( editorPage, 'amp-story' );
		await previewPage.waitForSelector( '.amp-story-block-wrapper' );

		const [ elementHandle ] = await previewPage.$x( '//amp-story-page/@auto-advance-after' );
		const secondsHandle = await elementHandle.getProperty( 'value' );
		const seconds = await secondsHandle.jsonValue();
		expect( seconds ).toStrictEqual( '15s' );
	} );

	it( 'should consider animations time when setting the page advancement', async () => {
		await insertBlock( 'Author' );

		const animationTypeSelector = '.is-opened select.components-select-control__input';
		await page.waitForSelector( animationTypeSelector );
		await page.select( animationTypeSelector, 'pulse' );

		const animationDelaySelector = 'input[aria-label="Delay (ms)"]';
		await page.waitForSelector( animationDelaySelector );
		await page.type( animationDelaySelector, '1500' );

		await selectBlockByClientId(
			( await getAllBlocks() )[ 0 ].clientId
		);

		const pageAdvancementSelector = '.components-select-control__input';
		await page.waitForSelector( pageAdvancementSelector );
		await page.select( pageAdvancementSelector, 'time' );

		const secondsSelector = 'input[aria-label="Time in seconds"]';
		await page.waitForSelector( secondsSelector );

		expect( await page.evaluate( ( selector ) => {
			return document.querySelector( selector ).value;
		}, secondsSelector ) ).toBe( '2' );
	} );
} );
<|endoftext|>