<commit_before>var assert = require('assert');
var fs = require('fs');
var swPrecache = require('../sw-precache.js');
var URL = require('dom-urls');

var NOOP = function() {};
var TEMP_FILE = 'test/data/temp.txt';

describe('sw-precache core functionality', function() {
  before(function() {
    fs.writeFileSync(TEMP_FILE, 'initial data');
  });

  it('should produce valid JavaScript', function(done) {
    swPrecache({logger: NOOP}, function(error, responseString) {
      assert.ifError(error);
      assert.doesNotThrow(function() {
        new Function(responseString);
        done();
      });
    });
  });

  it('should produce the same output given the same input files', function(done) {
    var config = {
      logger: NOOP,
      staticFileGlobs: ['test/data/one/**']
    };

    swPrecache(config, function(error, responseStringOne) {
      assert.ifError(error);
      swPrecache(config, function(error, responseStringTwo) {
        assert.ifError(error);
        assert.strictEqual(responseStringOne, responseStringTwo);
        done();
      });
    });
  });

  it('should produce different output given different input files', function(done) {
    var configOne = {
      logger: NOOP,
      staticFileGlobs: ['test/data/one/**']
    };

    var configTwo = {
      logger: NOOP,
      staticFileGlobs: ['test/data/two/**']
    };

    swPrecache(configOne, function(error, responseStringOne) {
      assert.ifError(error);
      swPrecache(configTwo, function(error, responseStringTwo) {
        assert.ifError(error);
        assert.notStrictEqual(responseStringOne, responseStringTwo);
        done();
      });
    });
  });

  it('should produce the same output regardless of which order the globs are in', function(done) {
    var config = {
      logger: NOOP,
      staticFileGlobs: [
        'test/data/one/a.txt',
        'test/data/one/c.txt',
        'test/data/two/b.txt'
      ]
    };

    var configPrime = {
      logger: NOOP,
      staticFileGlobs: [
        'test/data/one/c.txt',
        'test/data/two/b.txt',
        'test/data/one/a.txt'
      ]
    };

    swPrecache(config, function(error, reponseString) {
      assert.ifError(error);
      swPrecache(configPrime, function(error, responseStringPrime) {
        assert.ifError(error);
        assert.strictEqual(reponseString, responseStringPrime);
        done();
      });
    });
  });

  it('should produce different output when the contents of an input file changes', function(done) {
    var config = {
      logger: NOOP,
      staticFileGlobs: [TEMP_FILE]
    };

    swPrecache(config, function(error, responseString) {
      assert.ifError(error);
      fs.appendFileSync(TEMP_FILE, 'new data');
      swPrecache(config, function(error, responseStringPrime) {
        assert.ifError(error);
        assert.notStrictEqual(responseString, responseStringPrime);
        done();
      });
    });
  });

  after(function() {
    fs.unlinkSync(TEMP_FILE);
  });
});

describe('sw-precache parameters', function() {
  it('should exclude files larger than maximumFileSizeToCacheInBytes', function(done) {
    var file = 'test/data/one/a.txt';
    var size = fs.statSync(file).size;
    var config = {
      logger: NOOP,
      staticFileGlobs: [file],
      maximumFileSizeToCacheInBytes: size - 1
    };

    swPrecache(config, function(error, responseStringSmaller) {
      assert.ifError(error);
      config.maximumFileSizeToCacheInBytes = size;
      swPrecache(config, function(error, responseStringLarger) {
        assert.ifError(error);
        assert(responseStringSmaller.length < responseStringLarger.length);
        done();
      });
    });
  });
});

describe('stripIgnoredUrlParameters', function() {
  var testUrl = 'http://example.com/index.html?one=1&two=2&three=3&four&five=5';
  var localStripIgnoredUrlParameters;
  // This is very, very ugly. But, I wanted to write tests?
  before(function(done) {
    swPrecache({logger: NOOP}, function(error, responseString) {
      assert.ifError(error);
      var matches = responseString.match(/^function stripIgnoredUrlParameters[^]+?^\}/m);
      assert.notEqual(matches, null, 'Unable to parse function using regex.');
      eval(matches[0]);
      localStripIgnoredUrlParameters = stripIgnoredUrlParameters;
      done();
    });
  });

  it('should strip out all parameters when [/./] is used', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl, [/./]);
    assert.strictEqual(strippedUrl, 'http://example.com/index.html');
    done();
  });

  it('should not do anything when [] is used', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl, []);
    assert.strictEqual(strippedUrl, testUrl);
    done();
  });

  it('should not do anything when a non-matching regex is used', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl, [/dummy/]);
    assert.strictEqual(strippedUrl, testUrl);
    done();
  });

  it('should work when a key without a value is matched', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl, [/four/]);
    assert.strictEqual(strippedUrl, 'http://example.com/index.html?one=1&two=2&three=3&five=5');
    done();
  });

  it('should work when a single regex matches multiple keys', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl, [/^t/]);
    assert.strictEqual(strippedUrl, 'http://example.com/index.html?one=1&four&five=5');
    done();
  });

  it('should work when a multiples regexes each match multiple keys', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl, [/^t/, /^f/]);
    assert.strictEqual(strippedUrl, 'http://example.com/index.html?one=1');
    done();
  });

  it('should work when there\'s a hash fragment', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl + '#hash', [/^t/, /^f/]);
    assert.strictEqual(strippedUrl, 'http://example.com/index.html?one=1#hash');
    done();
  });
});
<commit_msg>Test for case where there's no query string.<commit_after>var assert = require('assert');
var fs = require('fs');
var swPrecache = require('../sw-precache.js');
var URL = require('dom-urls');

var NOOP = function() {};
var TEMP_FILE = 'test/data/temp.txt';

describe('sw-precache core functionality', function() {
  before(function() {
    fs.writeFileSync(TEMP_FILE, 'initial data');
  });

  it('should produce valid JavaScript', function(done) {
    swPrecache({logger: NOOP}, function(error, responseString) {
      assert.ifError(error);
      assert.doesNotThrow(function() {
        new Function(responseString);
        done();
      });
    });
  });

  it('should produce the same output given the same input files', function(done) {
    var config = {
      logger: NOOP,
      staticFileGlobs: ['test/data/one/**']
    };

    swPrecache(config, function(error, responseStringOne) {
      assert.ifError(error);
      swPrecache(config, function(error, responseStringTwo) {
        assert.ifError(error);
        assert.strictEqual(responseStringOne, responseStringTwo);
        done();
      });
    });
  });

  it('should produce different output given different input files', function(done) {
    var configOne = {
      logger: NOOP,
      staticFileGlobs: ['test/data/one/**']
    };

    var configTwo = {
      logger: NOOP,
      staticFileGlobs: ['test/data/two/**']
    };

    swPrecache(configOne, function(error, responseStringOne) {
      assert.ifError(error);
      swPrecache(configTwo, function(error, responseStringTwo) {
        assert.ifError(error);
        assert.notStrictEqual(responseStringOne, responseStringTwo);
        done();
      });
    });
  });

  it('should produce the same output regardless of which order the globs are in', function(done) {
    var config = {
      logger: NOOP,
      staticFileGlobs: [
        'test/data/one/a.txt',
        'test/data/one/c.txt',
        'test/data/two/b.txt'
      ]
    };

    var configPrime = {
      logger: NOOP,
      staticFileGlobs: [
        'test/data/one/c.txt',
        'test/data/two/b.txt',
        'test/data/one/a.txt'
      ]
    };

    swPrecache(config, function(error, reponseString) {
      assert.ifError(error);
      swPrecache(configPrime, function(error, responseStringPrime) {
        assert.ifError(error);
        assert.strictEqual(reponseString, responseStringPrime);
        done();
      });
    });
  });

  it('should produce different output when the contents of an input file changes', function(done) {
    var config = {
      logger: NOOP,
      staticFileGlobs: [TEMP_FILE]
    };

    swPrecache(config, function(error, responseString) {
      assert.ifError(error);
      fs.appendFileSync(TEMP_FILE, 'new data');
      swPrecache(config, function(error, responseStringPrime) {
        assert.ifError(error);
        assert.notStrictEqual(responseString, responseStringPrime);
        done();
      });
    });
  });

  after(function() {
    fs.unlinkSync(TEMP_FILE);
  });
});

describe('sw-precache parameters', function() {
  it('should exclude files larger than maximumFileSizeToCacheInBytes', function(done) {
    var file = 'test/data/one/a.txt';
    var size = fs.statSync(file).size;
    var config = {
      logger: NOOP,
      staticFileGlobs: [file],
      maximumFileSizeToCacheInBytes: size - 1
    };

    swPrecache(config, function(error, responseStringSmaller) {
      assert.ifError(error);
      config.maximumFileSizeToCacheInBytes = size;
      swPrecache(config, function(error, responseStringLarger) {
        assert.ifError(error);
        assert(responseStringSmaller.length < responseStringLarger.length);
        done();
      });
    });
  });
});

describe('stripIgnoredUrlParameters', function() {
  var testUrl = 'http://example.com/index.html?one=1&two=2&three=3&four&five=5';
  var localStripIgnoredUrlParameters;
  // This is very, very ugly. But, I wanted to write tests?
  before(function(done) {
    swPrecache({logger: NOOP}, function(error, responseString) {
      assert.ifError(error);
      var matches = responseString.match(/^function stripIgnoredUrlParameters[^]+?^\}/m);
      assert.notEqual(matches, null, 'Unable to parse function using regex.');
      eval(matches[0]);
      localStripIgnoredUrlParameters = stripIgnoredUrlParameters;
      done();
    });
  });

  it('should return the same URL when the URL doesn\'t have a query string', function(done) {
    var querylessUrl = 'http://example.com/index.html';
    var strippedUrl = localStripIgnoredUrlParameters(querylessUrl, [/./]);
    assert.strictEqual(strippedUrl, querylessUrl);
    done();
  });

  it('should strip out all parameters when [/./] is used', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl, [/./]);
    assert.strictEqual(strippedUrl, 'http://example.com/index.html');
    done();
  });

  it('should not do anything when [] is used', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl, []);
    assert.strictEqual(strippedUrl, testUrl);
    done();
  });

  it('should not do anything when a non-matching regex is used', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl, [/dummy/]);
    assert.strictEqual(strippedUrl, testUrl);
    done();
  });

  it('should work when a key without a value is matched', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl, [/four/]);
    assert.strictEqual(strippedUrl, 'http://example.com/index.html?one=1&two=2&three=3&five=5');
    done();
  });

  it('should work when a single regex matches multiple keys', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl, [/^t/]);
    assert.strictEqual(strippedUrl, 'http://example.com/index.html?one=1&four&five=5');
    done();
  });

  it('should work when a multiples regexes each match multiple keys', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl, [/^t/, /^f/]);
    assert.strictEqual(strippedUrl, 'http://example.com/index.html?one=1');
    done();
  });

  it('should work when there\'s a hash fragment', function(done) {
    var strippedUrl = localStripIgnoredUrlParameters(testUrl + '#hash', [/^t/, /^f/]);
    assert.strictEqual(strippedUrl, 'http://example.com/index.html?one=1#hash');
    done();
  });
});
<|endoftext|>


<commit_before>module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        bower: {
            install: {
                options: {
                    targetDir: 'app/lib'
                }
            }
        },
        less: {
            dev: {
                options: {
                    paths: ["app/less"],
                    sourceMap: true
                    //sourceMapFilename: 'addressbook.css.map'
                },
                files: {
                    "app/css/addressbook.css": "app/less/addressbook.less"
                }
            },
            dist: {
                options: {
                    paths: ["app/less"],
                    compress: true
                },
                files: {
                    "dist/css/addressbook.css": "app/less/addressbook.less"
                }
            }
        },
        watch: {
            files: ['app/less/**/*.less'],
            tasks: ['less:dev']
        },
        clean: ["app/css", "app/js", "dist"]
    });

    grunt.loadNpmTasks('grunt-bower-task');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-clean');

    grunt.registerTask('deps', ['bower']);
    grunt.registerTask('test', []);
    grunt.registerTask('dist', ['less:dist']);

};<commit_msg>fixed less sourceMap root path.<commit_after>module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        bower: {
            install: {
                options: {
                    targetDir: 'app/lib'
                }
            }
        },
        less: {
            dev: {
                options: {
                    sourceMap: true,
                    sourceMapRootpath: '../../'
                },
                files: {
                    "app/css/addressbook.css": "app/less/addressbook.less"
                }
            },
            dist: {
                options: {
                    paths: ["app/less"],
                    compress: true
                },
                files: {
                    "dist/css/addressbook.css": "app/less/addressbook.less"
                }
            }
        },
        watch: {
            files: ['app/less/**/*.less'],
            tasks: ['less:dev']
        },
        clean: ["app/css", "app/js", "dist"]
    });

    grunt.loadNpmTasks('grunt-bower-task');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-clean');

    grunt.registerTask('deps', ['bower']);
    grunt.registerTask('test', []);
    grunt.registerTask('dist', ['less:dist']);

};<|endoftext|>


<commit_before>/*
 *  Copyright 2011 Rackspace
 *
 *  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.
 *
 */
var util = require('util');

var et = require('elementtree');
var async = require('async');
var _ = require('underscore');

var utils = require('../../utils');

var DAY = 1000*60*60*24;

var days_since_epoch = function(time){
  var date = new Date(time);
  return parseInt(date.valueOf()/DAY, 10);
};

module.exports.poll_interval = 30 * 60 * 1000;

module.exports = utils.make_class({

  sprint_window: 22,
  delimiter: "▼",

  init: function(payload) {
    var self = this;
    self.api_config = payload.get_config();
    self.sprints = [];
    self.sprint_mapper = {};
    self.sprint_ids_to_names = {};

    async.waterfall([
      _.bind(self.get_sprint_options, self),
      _.bind(self.request_and_parse, self),
      _.bind(self.parse_sprints, self),
      _.bind(self.request_assets, self),
      _.bind(self.parse_assets, self)],
      function(err, results){
        payload.set_data(err, results);
    });
  },
  get_v1_options: function (get_query){
    var self = this;
    return {
      port: self.api_config.port,
      host: self.api_config.host,
      path: ['/',
             self.api_config.name,
             "/rest-1.v1",
             get_query
             ].join(""),
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Basic ' + new Buffer(self.api_config.auth).toString('base64')
      }
    };
  },
  get_sprint_options: function (cb){
    var self = this;
    var now = new Date();
    var begin = new Date(now.valueOf() - 365*DAY);
    var scope = self.api_config.project[0]; // We need any of the appropriate scopes.
    var path = util.format("/Data/Timebox?where=Schedule.ScheduledScopes='Scope:%s';BeginDate>='%s';BeginDate<='%s'&sel=Schedule.ScheduledScopes,BeginDate,EndDate,Name,Schedule.ScheduledScopes.Name",
        scope, begin.toISOString(), now.toISOString());
    var options = self.get_v1_options(path);
    cb(null, options);
  },
  set_sprints: function(sprints){
    var self = this;
    // take the last three and hope for the best
    self.sprints = sprints.slice(-3);
    _.each(sprints, function(sprint){
      self.sprint_mapper[sprint.id] = sprint;
    });

    _.each(sprints, function(sprint){
      var name;
      var value;
      for (var i = 0; sprint.attributes['Schedule.ScheduledScopes.Name'].values[i]; i++) {
        name = sprint.relations['Schedule.ScheduledScopes'][i].idref.split(':')[1];
        value = sprint.attributes['Schedule.ScheduledScopes.Name'].values[i];
        self.sprint_ids_to_names[name] = value;
      }
    });
    return self.sprints;
  },
  get_sprint: function(sprint_id){
    var self = this;
    return self.sprint_mapper[sprint_id];
  },
  parse_sprints: function (assets, cb){
    var self = this;
    var sprints = [];
    _.each(assets, function(asset){
      sprints.push(asset);
    });
    self.set_sprints(sprints);
    cb(null, self.sprints);
  },
  _sprint_asset_request_maker: function(sprint, scope, type){
    var self = this;
    var selection = ["DetailEstimate", "ChangeDate", "AssetState", "Status.Name", "CreateDate"].join(',');
    return function(cb){
      var path = util.format("/Hist/%s?where=Timebox='%s';Scope='Scope:%s'&sel=%s", type, sprint.id, scope, selection);
      var options = self.get_v1_options(path);
      self.request_and_parse(options, cb);
    };
  },
  request_and_parse: function (options, cb){
    var self = this;
    utils.request_maker(options, function(err, results){
      if (err){
        return cb(err);
      }
      utils.parse_v1(results.data, cb);
    });
  },
  request_assets: function(sprints, cb){
    var self = this;
    var defect_requests = {};
    var task_requests = {};

    _.each(self.api_config.project, function(scope) {
      _.each(sprints, function(sprint){
        defect_requests[scope + self.delimiter + sprint.id] = self._sprint_asset_request_maker(sprint, scope, 'Defect');
        task_requests[scope + self.delimiter + sprint.id] = self._sprint_asset_request_maker(sprint, scope, 'Task');
      });
    });

    async.parallel({
      Defects: function(_cb){
        async.parallel(defect_requests, _cb);
      },
      Tasks: function(_cb){
        async.parallel(task_requests, _cb);
      }
    }, cb);
  },
  parse_histories: function(history) {
    var asset;
    var assets = {};
    var i = 1;
    var id;
    var state;
    var closed_states = {
      "128": i++,
      "Accepted": i++,
      "Closed": i++,
      "Completed": i++
    };
    for (i=0; i<history.length; i++){
      asset = history[i];
      id = asset.id.split(":")[1];
      state = asset.attributes['Status.Name'] ? asset.attributes['Status.Name'].text : null;
      if (!state){
        state = parseInt(asset.attributes.AssetState.text, 10);
        // some assets have a 234 or similarly undocumented states.
        // 200,208,255 are all synonyms for deleted
        if (state > 128){
          continue;
        }
      }
      asset.state = closed_states[state] || 0;
      asset.closed = asset.state > 0 ? true : false;
      asset.id = id;
      if ( assets[id] === undefined) {
        assets[id] = asset;
        continue;
      }
      if ( asset.state > assets[id].state ){
        assets[id] = asset;
      }
    }
    return _.values(assets);
  },
  bin_assets: function(assets, sprint_start_day, bin){
    var self = this;
    bin = bin || [];
    var _asset_binner = function(asset){
      var start = days_since_epoch(asset.attributes.CreateDate.text);
      var end = days_since_epoch(asset.attributes.ChangeDate.text);
      var estimate = parseInt(asset.attributes.DetailEstimate.text || 1, 10);
      var i;
      // how long did the asset live in days (not assuming anything aboot being closed)?
      var run_date = end - start;
      // when, in days, does the asset come into being from the start of the sprint?
      //(can be negative, positive, etc)
      var days_till_starts = start - sprint_start_day;
      // iterate through the sprint window starting on days_till_starts where i is in days
      i = days_till_starts - 1;
      while ( i <= self.sprint_window ){
        i += 1;
        // i must be positive (some assets are reasigned to new sprints)
        if (i<0){
          continue;
        }
        // if the thing was closed and we have passed that day, move on
        if ( asset.closed && i > (end - sprint_start_day) ){
          break;
        }
        // initialize bins to 0
        if (!bin[i]){
          bin[i] = 0;
        }
        // if the thing is still alive, or if it was never closed, add the estimates.
        if ( i <= run_date || !asset.closed ){
          bin[i] += estimate;
        }
      }
    };
    _.each(assets, _asset_binner);
    return bin;
  },
  parse_assets: function(asset_classes, cb){
    var self = this;
    var bins = {};

    _.each(asset_classes, function(assets, asset_type){
      _.each(assets, function(asset_list, scope_sprint){
        var this_sprint;
        var sprint_name;
        var sprint_start_day;
        var scope;
        var sprint_id;
        var bin;
        var scope_name;

        scope = scope_sprint.split(self.delimiter)[0];
        scope_name = self.sprint_ids_to_names[scope];

        if (bins[scope_name] === undefined) {
          bins[scope_name] = {};
        }
        if (bins.Total === undefined) {
          bins.Total = {};
        }
        if (bins[scope_name][asset_type] === undefined) {
          bins[scope_name][asset_type] = {};
        }
        if (bins.Total[asset_type] === undefined) {
          bins.Total[asset_type] = {};
        }

        sprint_id = scope_sprint.split(self.delimiter)[1];
        bins[scope_name][asset_type] = bins[scope_name][asset_type] || {};

        this_sprint = self.get_sprint(sprint_id);
        sprint_name = this_sprint.attributes.Name.text;
        sprint_start_day = days_since_epoch(this_sprint.attributes.BeginDate.text);
        asset_list = self.parse_histories(asset_list);

        bin = self.bin_assets(asset_list, sprint_start_day);
        bins.Total[asset_type][sprint_name] = self.bin_assets(asset_list, sprint_start_day, bins.Total[asset_type][sprint_name]);
        // assets in sprint
        bins[scope_name][asset_type][sprint_name] = bin;
      });
    });
    cb(null, bins);
  }
});
<commit_msg>simplified a ternary<commit_after>/*
 *  Copyright 2011 Rackspace
 *
 *  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.
 *
 */
var util = require('util');

var et = require('elementtree');
var async = require('async');
var _ = require('underscore');

var utils = require('../../utils');

var DAY = 1000*60*60*24;

var days_since_epoch = function(time){
  var date = new Date(time);
  return parseInt(date.valueOf()/DAY, 10);
};

module.exports.poll_interval = 30 * 60 * 1000;

module.exports = utils.make_class({

  sprint_window: 22,
  delimiter: "▼",

  init: function(payload) {
    var self = this;
    self.api_config = payload.get_config();
    self.sprints = [];
    self.sprint_mapper = {};
    self.sprint_ids_to_names = {};

    async.waterfall([
      _.bind(self.get_sprint_options, self),
      _.bind(self.request_and_parse, self),
      _.bind(self.parse_sprints, self),
      _.bind(self.request_assets, self),
      _.bind(self.parse_assets, self)],
      function(err, results){
        payload.set_data(err, results);
    });
  },
  get_v1_options: function (get_query){
    var self = this;
    return {
      port: self.api_config.port,
      host: self.api_config.host,
      path: ['/',
             self.api_config.name,
             "/rest-1.v1",
             get_query
             ].join(""),
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Basic ' + new Buffer(self.api_config.auth).toString('base64')
      }
    };
  },
  get_sprint_options: function (cb){
    var self = this;
    var now = new Date();
    var begin = new Date(now.valueOf() - 365*DAY);
    var scope = self.api_config.project[0]; // We need any of the appropriate scopes.
    var path = util.format("/Data/Timebox?where=Schedule.ScheduledScopes='Scope:%s';BeginDate>='%s';BeginDate<='%s'&sel=Schedule.ScheduledScopes,BeginDate,EndDate,Name,Schedule.ScheduledScopes.Name",
        scope, begin.toISOString(), now.toISOString());
    var options = self.get_v1_options(path);
    cb(null, options);
  },
  set_sprints: function(sprints){
    var self = this;
    // take the last three and hope for the best
    self.sprints = sprints.slice(-3);
    _.each(sprints, function(sprint){
      self.sprint_mapper[sprint.id] = sprint;
    });

    _.each(sprints, function(sprint){
      var name;
      var value;
      for (var i = 0; sprint.attributes['Schedule.ScheduledScopes.Name'].values[i]; i++) {
        name = sprint.relations['Schedule.ScheduledScopes'][i].idref.split(':')[1];
        value = sprint.attributes['Schedule.ScheduledScopes.Name'].values[i];
        self.sprint_ids_to_names[name] = value;
      }
    });
    return self.sprints;
  },
  get_sprint: function(sprint_id){
    var self = this;
    return self.sprint_mapper[sprint_id];
  },
  parse_sprints: function (assets, cb){
    var self = this;
    var sprints = [];
    _.each(assets, function(asset){
      sprints.push(asset);
    });
    self.set_sprints(sprints);
    cb(null, self.sprints);
  },
  _sprint_asset_request_maker: function(sprint, scope, type){
    var self = this;
    var selection = ["DetailEstimate", "ChangeDate", "AssetState", "Status.Name", "CreateDate"].join(',');
    return function(cb){
      var path = util.format("/Hist/%s?where=Timebox='%s';Scope='Scope:%s'&sel=%s", type, sprint.id, scope, selection);
      var options = self.get_v1_options(path);
      self.request_and_parse(options, cb);
    };
  },
  request_and_parse: function (options, cb){
    var self = this;
    utils.request_maker(options, function(err, results){
      if (err){
        return cb(err);
      }
      utils.parse_v1(results.data, cb);
    });
  },
  request_assets: function(sprints, cb){
    var self = this;
    var defect_requests = {};
    var task_requests = {};

    _.each(self.api_config.project, function(scope) {
      _.each(sprints, function(sprint){
        defect_requests[scope + self.delimiter + sprint.id] = self._sprint_asset_request_maker(sprint, scope, 'Defect');
        task_requests[scope + self.delimiter + sprint.id] = self._sprint_asset_request_maker(sprint, scope, 'Task');
      });
    });

    async.parallel({
      Defects: function(_cb){
        async.parallel(defect_requests, _cb);
      },
      Tasks: function(_cb){
        async.parallel(task_requests, _cb);
      }
    }, cb);
  },
  parse_histories: function(history) {
    var asset;
    var assets = {};
    var i = 1;
    var id;
    var state;
    var closed_states = {
      "128": i++,
      "Accepted": i++,
      "Closed": i++,
      "Completed": i++
    };
    for (i=0; i<history.length; i++){
      asset = history[i];
      id = asset.id.split(":")[1];
      state = asset.attributes['Status.Name'].text;
      if (!state){
        state = parseInt(asset.attributes.AssetState.text, 10);
        // some assets have a 234 or similarly undocumented states.
        // 200,208,255 are all synonyms for deleted
        if (state > 128){
          continue;
        }
      }
      asset.state = closed_states[state] || 0;
      asset.closed = asset.state > 0 ? true : false;
      asset.id = id;
      if ( assets[id] === undefined) {
        assets[id] = asset;
        continue;
      }
      if ( asset.state > assets[id].state ){
        assets[id] = asset;
      }
    }
    return _.values(assets);
  },
  bin_assets: function(assets, sprint_start_day, bin){
    var self = this;
    bin = bin || [];
    var _asset_binner = function(asset){
      var start = days_since_epoch(asset.attributes.CreateDate.text);
      var end = days_since_epoch(asset.attributes.ChangeDate.text);
      var estimate = parseInt(asset.attributes.DetailEstimate.text || 1, 10);
      var i;
      // how long did the asset live in days (not assuming anything aboot being closed)?
      var run_date = end - start;
      // when, in days, does the asset come into being from the start of the sprint?
      //(can be negative, positive, etc)
      var days_till_starts = start - sprint_start_day;
      // iterate through the sprint window starting on days_till_starts where i is in days
      i = days_till_starts - 1;
      while ( i <= self.sprint_window ){
        i += 1;
        // i must be positive (some assets are reasigned to new sprints)
        if (i<0){
          continue;
        }
        // if the thing was closed and we have passed that day, move on
        if ( asset.closed && i > (end - sprint_start_day) ){
          break;
        }
        // initialize bins to 0
        if (!bin[i]){
          bin[i] = 0;
        }
        // if the thing is still alive, or if it was never closed, add the estimates.
        if ( i <= run_date || !asset.closed ){
          bin[i] += estimate;
        }
      }
    };
    _.each(assets, _asset_binner);
    return bin;
  },
  parse_assets: function(asset_classes, cb){
    var self = this;
    var bins = {};

    _.each(asset_classes, function(assets, asset_type){
      _.each(assets, function(asset_list, scope_sprint){
        var this_sprint;
        var sprint_name;
        var sprint_start_day;
        var scope;
        var sprint_id;
        var bin;
        var scope_name;

        scope = scope_sprint.split(self.delimiter)[0];
        scope_name = self.sprint_ids_to_names[scope];

        if (bins[scope_name] === undefined) {
          bins[scope_name] = {};
        }
        if (bins.Total === undefined) {
          bins.Total = {};
        }
        if (bins[scope_name][asset_type] === undefined) {
          bins[scope_name][asset_type] = {};
        }
        if (bins.Total[asset_type] === undefined) {
          bins.Total[asset_type] = {};
        }

        sprint_id = scope_sprint.split(self.delimiter)[1];
        bins[scope_name][asset_type] = bins[scope_name][asset_type] || {};

        this_sprint = self.get_sprint(sprint_id);
        sprint_name = this_sprint.attributes.Name.text;
        sprint_start_day = days_since_epoch(this_sprint.attributes.BeginDate.text);
        asset_list = self.parse_histories(asset_list);

        bin = self.bin_assets(asset_list, sprint_start_day);
        bins.Total[asset_type][sprint_name] = self.bin_assets(asset_list, sprint_start_day, bins.Total[asset_type][sprint_name]);
        // assets in sprint
        bins[scope_name][asset_type][sprint_name] = bin;
      });
    });
    cb(null, bins);
  }
});
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var path = require('path');

var lib = {
	/**
	 * Function that find the root path where grunt plugins are installed.
	 *
	 * @method findRoot
	 * @return String rootPath
	 */
	findRoot: function () {
		var cwd = process.cwd();
		var rootPath = cwd;
		var newRootPath = null;
		while (!fs.existsSync(path.join(process.cwd(), "node_modules/grunt"))) {
			process.chdir("..");
			newRootPath = process.cwd();
			if (newRootPath === rootPath) {
				return;
			}
			rootPath = newRootPath;
		}
		process.chdir(cwd);
		return rootPath;
	},
	/**
	 * Function load the npm tasks from the root path
	 *
	 * @method loadTasks
	 * @param grunt {Object} The grunt instance
	 * @param tasks {Array} Array of tasks as string
	 */
	loadTasks: function (grunt, rootPath, tasks) {
		tasks.forEach(function (name) {
			if (name === 'grunt-cli') return;
			var cwd = process.cwd();
			process.chdir(rootPath); // load files from proper root, I don't want to install everything locally per module!
			grunt.loadNpmTasks(name);
			process.chdir(cwd);
		});
	}
};

module.exports = function (grunt) {
	//Loading the needed plugins to run the grunt tasks
	var pluginsRootPath = lib.findRoot();
	lib.loadTasks(grunt, pluginsRootPath, ['grunt-contrib-jshint', 'grunt-jsdoc', 'grunt-contrib-clean', 'grunt-mocha-test', 'grunt-env'
		, 'grunt-istanbul', 'grunt-coveralls']);
	grunt.initConfig({
		//Defining jshint tasks
		jshint: {
			options: {
				"bitwise": true,
				"eqeqeq": true,
				"forin": true,
				"newcap": true,
				"noarg": true,
				"undef": true,
				"unused": false,
				"eqnull": true,
				"laxcomma": true,
				"loopfunc": true,
				"sub": true,
				"supernew": true,
				"validthis": true,
				"node": true,
				"maxerr": 100,
				"indent": 2,
				"globals": {
					"describe": false,
					"it": false,
					"before": false,
					"beforeEach": false,
					"after": false,
					"afterEach": false
				},
				ignores: ['test/coverage/**/*.js']
			},
			files: {
				src: ['**/*.js']
			},
			gruntfile: {
				src: 'Gruntfile.js'
			}
		},
		// jsdoc: {
		//   doc : {
		//     src: ['soajs/**/*.js'],
		//     jsdoc: pluginsRootPath+'/node_modules/grunt-jsdoc/node_modules/jsdoc/jsdoc',
		//     options: {
		//       dest: 'doc',
		//     }
		//   }
		// },

		env: {
			mochaTest: {
				// NODE_ENV: 'test',
				// APP_DIR: process.cwd(),
				SOAJS_ENV: 'dev',
				APP_DIR_FOR_CODE_COVERAGE: '../',
				SOAJS_SRVIP: '127.0.0.1'
			},
			coverage: {
				// NODE_ENV: 'test',
				// APP_DIR: process.cwd(),
				SOAJS_ENV: 'dev',
				APP_DIR_FOR_CODE_COVERAGE: '../test/coverage/instrument/',
				SOAJS_SRVIP: '127.0.0.1'
			}
		},

		clean: {
			doc: {
				src: ['doc/']
			},
			coverage: {
				src: ['test/coverage/']
			}
		},

		instrument: {
			//files: ['example01/*.js', 'example02/*.js', 'example03/*.js' ],
			files: ['example01/*.js', 'example02/*.js', 'example03/*.js', 'example04/*.js', 'hello_world/*.js'],
			//files: ['**/*.js'],
			options: {
				lazy: false,
				basePath: 'test/coverage/instrument/'
			}
		},

		storeCoverage: {
			options: {
				dir: 'test/coverage/reports'
			}
		},

		makeReport: {
			src: 'test/coverage/reports/**/*.json',
			options: {
				type: 'lcov',
				dir: 'test/coverage/reports',
				print: 'detail'
			}
		},

		mochaTest: {
			unit: {
				options: {
					reporter: 'spec',
					timeout: 90000
				},
				src: ['test/unit/*.js']
			},
			integration: {
				options: {
					reporter: 'spec',
					timeout: 90000
				},
				src: ['test/integration/_servers.test.js']
			}
		},

		coveralls: {
			options: {
				// LCOV coverage file relevant to every target
				src: 'test/coverage/reports/lcov.info',

				// When true, grunt-coveralls will only print a warning rather than
				// an error, to prevent CI builds from failing unnecessarily (e.g. if
				// coveralls.io is down). Optional, defaults to false.
				force: false
			},
			your_target: {
				// Target-specific LCOV coverage file
				src: 'test/coverage/reports/lcov.info'
			}
		}
	});

	process.env.SHOW_LOGS = grunt.option('showLogs');
	grunt.registerTask("default", ['jshint']);
	grunt.registerTask("integration", ['env:mochaTest', 'mochaTest:integration']);
	grunt.registerTask("unit", ['env:mochaTest', 'mochaTest:unit']);
	grunt.registerTask("test", ['clean', 'env:coverage', 'instrument', 'mochaTest:unit', 'mochaTest:integration']);
	grunt.registerTask("coverage", ['clean', 'env:coverage', 'instrument', 'mochaTest:integration', 'storeCoverage', 'makeReport', 'coveralls']);
	//grunt.registerTask("coverage", ['clean', 'env:coverage', 'instrument', 'mochaTest:integration', 'storeCoverage', 'makeReport']);

};

<commit_msg>passign oAuth through registry & struct, wiping db & forcing build All in ex, minor fixes<commit_after>'use strict';

var fs = require('fs');
var path = require('path');

var lib = {
	/**
	 * Function that find the root path where grunt plugins are installed.
	 *
	 * @method findRoot
	 * @return String rootPath
	 */
	findRoot: function () {
		var cwd = process.cwd();
		var rootPath = cwd;
		var newRootPath = null;
		while (!fs.existsSync(path.join(process.cwd(), "node_modules/grunt"))) {
			process.chdir("..");
			newRootPath = process.cwd();
			if (newRootPath === rootPath) {
				return;
			}
			rootPath = newRootPath;
		}
		process.chdir(cwd);
		return rootPath;
	},
	/**
	 * Function load the npm tasks from the root path
	 *
	 * @method loadTasks
	 * @param grunt {Object} The grunt instance
	 * @param tasks {Array} Array of tasks as string
	 */
	loadTasks: function (grunt, rootPath, tasks) {
		tasks.forEach(function (name) {
			if (name === 'grunt-cli') return;
			var cwd = process.cwd();
			process.chdir(rootPath); // load files from proper root, I don't want to install everything locally per module!
			grunt.loadNpmTasks(name);
			process.chdir(cwd);
		});
	}
};

module.exports = function (grunt) {
	//Loading the needed plugins to run the grunt tasks
	var pluginsRootPath = lib.findRoot();
	lib.loadTasks(grunt, pluginsRootPath, ['grunt-contrib-jshint', 'grunt-jsdoc', 'grunt-contrib-clean', 'grunt-mocha-test', 'grunt-env'
		, 'grunt-istanbul', 'grunt-coveralls']);
	grunt.initConfig({
		//Defining jshint tasks
		jshint: {
			options: {
				"bitwise": true,
				"eqeqeq": true,
				"forin": true,
				"newcap": true,
				"noarg": true,
				"undef": true,
				"unused": false,
				"eqnull": true,
				"laxcomma": true,
				"loopfunc": true,
				"sub": true,
				"supernew": true,
				"validthis": true,
				"node": true,
				"maxerr": 100,
				"indent": 2,
				"globals": {
					"describe": false,
					"it": false,
					"before": false,
					"beforeEach": false,
					"after": false,
					"afterEach": false
				},
				ignores: ['test/coverage/**/*.js']
			},
			files: {
				src: ['**/*.js']
			},
			gruntfile: {
				src: 'Gruntfile.js'
			}
		},
		// jsdoc: {
		//   doc : {
		//     src: ['soajs/**/*.js'],
		//     jsdoc: pluginsRootPath+'/node_modules/grunt-jsdoc/node_modules/jsdoc/jsdoc',
		//     options: {
		//       dest: 'doc',
		//     }
		//   }
		// },

		env: {
			mochaTest: {
				// NODE_ENV: 'test',
				// APP_DIR: process.cwd(),
				SOAJS_REGISTRY_BUILDALL: true,
				SOAJS_ENV: 'dev',
				APP_DIR_FOR_CODE_COVERAGE: '../',
				SOAJS_SRVIP: '127.0.0.1'
			},
			coverage: {
				// NODE_ENV: 'test',
				// APP_DIR: process.cwd(),
				SOAJS_REGISTRY_BUILDALL: true,
				SOAJS_ENV: 'dev',
				APP_DIR_FOR_CODE_COVERAGE: '../test/coverage/instrument/',
				SOAJS_SRVIP: '127.0.0.1'
			}
		},

		clean: {
			doc: {
				src: ['doc/']
			},
			coverage: {
				src: ['test/coverage/']
			}
		},

		instrument: {
			//files: ['example01/*.js', 'example02/*.js', 'example03/*.js' ],
			files: ['example01/*.js', 'example02/*.js', 'example03/*.js', 'example04/*.js', 'hello_world/*.js'],
			//files: ['**/*.js'],
			options: {
				lazy: false,
				basePath: 'test/coverage/instrument/'
			}
		},

		storeCoverage: {
			options: {
				dir: 'test/coverage/reports'
			}
		},

		makeReport: {
			src: 'test/coverage/reports/**/*.json',
			options: {
				type: 'lcov',
				dir: 'test/coverage/reports',
				print: 'detail'
			}
		},

		mochaTest: {
			unit: {
				options: {
					reporter: 'spec',
					timeout: 90000
				},
				src: ['test/unit/*.js']
			},
			integration: {
				options: {
					reporter: 'spec',
					timeout: 90000
				},
				src: ['test/integration/_servers.test.js']
			}
		},

		coveralls: {
			options: {
				// LCOV coverage file relevant to every target
				src: 'test/coverage/reports/lcov.info',

				// When true, grunt-coveralls will only print a warning rather than
				// an error, to prevent CI builds from failing unnecessarily (e.g. if
				// coveralls.io is down). Optional, defaults to false.
				force: false
			},
			your_target: {
				// Target-specific LCOV coverage file
				src: 'test/coverage/reports/lcov.info'
			}
		}
	});

	process.env.SHOW_LOGS = grunt.option('showLogs');
	grunt.registerTask("default", ['jshint']);
	grunt.registerTask("integration", ['env:mochaTest', 'mochaTest:integration']);
	grunt.registerTask("unit", ['env:mochaTest', 'mochaTest:unit']);
	grunt.registerTask("test", ['clean', 'env:coverage', 'instrument', 'mochaTest:unit', 'mochaTest:integration']);
	grunt.registerTask("coverage", ['clean', 'env:coverage', 'instrument', 'mochaTest:integration', 'storeCoverage', 'makeReport', 'coveralls']);
	//grunt.registerTask("coverage", ['clean', 'env:coverage', 'instrument', 'mochaTest:integration', 'storeCoverage', 'makeReport']);

};

<|endoftext|>


<commit_before>import Adapter from 'src/adapter';
import bidfactory from 'src/bidfactory';
import bidmanager from 'src/bidmanager';
import adLoader from 'src/adloader';
import * as utils from 'src/utils';
import { STATUS } from 'src/constants';
import adaptermanager from 'src/adaptermanager';

function Spotx() {
  let baseAdapter = new Adapter('Spotx');
  let bidReq;
  let KVP_Object;

  baseAdapter.callBids = function(bidRequest) {
    if (!bidRequest || !bidRequest.bids || bidRequest.bids.length === 0) {
      return;
    }
    bidReq = bidRequest.bids[0] || [];

    if (!validateParams(bidReq)) {
      console.log('Bid Request does not contain valid parameters.');
      return;
    }

    loadDSDK();
  };

  // Load the SpotX Direct AdOS SDK onto the page
  function loadDSDK() {
    var channelId = bidReq.params.video.channel_id;
    adLoader.loadScript('//js.spotx.tv/directsdk/v1/' + channelId + '.js', initDSDK, true);
  }

  // We have a Direct AdOS SDK! Set options and initialize it!
  function initDSDK() {
    var options = bidReq.params.video;

    // If we are passed a id string set the slot and video slot to the element using that id.
    if (typeof options.slot === 'string') {
      options.slot = document.getElementById(bidReq.params.video.slot);
    }
    if (typeof options.video_slot === 'string') {
      options.video_slot = document.getElementById(bidReq.params.video.video_slot);
    }

    var directAdOS = new SpotX.DirectAdOS(options);

    directAdOS.getAdServerKVPs().then(function(adServerKVPs) {
      // Got an ad back. Build a successful response.
      var resp = {
        bids: []
      };
      var bid = {};

      bid.cmpID = bidReq.params.video.channel_id;
      bid.cpm = adServerKVPs.spotx_bid;
      bid.url = adServerKVPs.spotx_ad_key;
      bid.cur = 'USD';
      bid.bidderCode = 'spotx';
      var sizes = utils.isArray(bidReq.sizes[0]) ? bidReq.sizes[0] : bidReq.sizes;
      bid.height = sizes[1];
      bid.width = sizes[0];
      resp.bids.push(bid);
      KVP_Object = adServerKVPs;
      handleResponse(resp);
    }, function() {
      // No ad...
      handleResponse()
    });
  }

  function createBid(status) {
    var bid = bidfactory.createBid(status, utils.getBidRequest(bidReq.bidId));

    // Stuff we have no matter what
    bid.bidderCode = bidReq.bidder;
    bid.placementCode = bidReq.placementCode;
    bid.requestId = bidReq.requestId;
    bid.code = bidReq.bidder;

    // Stuff we only get with a successful response
    if (status === STATUS.GOOD && KVP_Object) {
      let url = '//search.spotxchange.com/ad/vast.html?key=' + KVP_Object.spotx_ad_key;
      bid.mediaType = 'video';

      bid.cpm = KVP_Object.spotx_bid;
      bid.vastUrl = url;
      bid.ad = url;

      var sizes = utils.isArray(bidReq.sizes[0]) ? bidReq.sizes[0] : bidReq.sizes;
      bid.height = sizes[1];
      bid.width = sizes[0];
    }

    return bid;
  }

  /* Notify Prebid of bid responses so bids can get in the auction */
  function handleResponse(response) {
    if (!response || !response.bids || !response.bids.length) {
      bidmanager.addBidResponse(bidReq.placementCode, createBid(STATUS.NO_BID));
    } else {
      bidmanager.addBidResponse(bidReq.placementCode, createBid(STATUS.GOOD, response.bids[0]));
    }
  }

  function validateParams(request) {
    if (typeof request.params !== 'object' && typeof request.params.video !== 'object') {
      return false;
    }

    // Check that all of our required parameters are defined.
    if (bidReq.params.video.channel_id === undefined || bidReq.params.video.slot === undefined || bidReq.params.video.video_slot === undefined) {
      return false;
    }
    return true;
  }

  return Object.assign(this, {
    callBids: baseAdapter.callBids,
    setBidderCode: baseAdapter.setBidderCode
  });
}

adaptermanager.registerBidAdapter(new Spotx(), 'spotx', {
  supportedMediaTypes: ['video']
});

module.exports = Spotx;
<commit_msg>Update spotx video adapter to set the spotx_ad_key used in DFP (#1614)<commit_after>import Adapter from 'src/adapter';
import bidfactory from 'src/bidfactory';
import bidmanager from 'src/bidmanager';
import adLoader from 'src/adloader';
import * as utils from 'src/utils';
import { STATUS } from 'src/constants';
import adaptermanager from 'src/adaptermanager';

function Spotx() {
  let baseAdapter = new Adapter('Spotx');
  let bidReq;
  let KVP_Object;

  const _defaultBidderSettings = {
    alwaysUseBid: true,
    adserverTargeting: [
      {
        key: 'hb_adid',
        val: function (bidResponse) {
          return bidResponse.spotx_ad_key;
        }
      }
    ]
  };

  bidmanager.registerDefaultBidderSetting('spotx', _defaultBidderSettings);

  baseAdapter.callBids = function(bidRequest) {
    if (!bidRequest || !bidRequest.bids || bidRequest.bids.length === 0) {
      return;
    }
    bidReq = bidRequest.bids[0] || [];

    if (!validateParams(bidReq)) {
      console.log('Bid Request does not contain valid parameters.');
      return;
    }

    loadDSDK();
  };

  // Load the SpotX Direct AdOS SDK onto the page
  function loadDSDK() {
    var channelId = bidReq.params.video.channel_id;
    adLoader.loadScript('//js.spotx.tv/directsdk/v1/' + channelId + '.js', initDSDK, true);
  }

  // We have a Direct AdOS SDK! Set options and initialize it!
  function initDSDK() {
    var options = bidReq.params.video;

    // If we are passed a id string set the slot and video slot to the element using that id.
    if (typeof options.slot === 'string') {
      options.slot = document.getElementById(bidReq.params.video.slot);
    }
    if (typeof options.video_slot === 'string') {
      options.video_slot = document.getElementById(bidReq.params.video.video_slot);
    }

    var directAdOS = new SpotX.DirectAdOS(options);

    directAdOS.getAdServerKVPs().then(function(adServerKVPs) {
      // Got an ad back. Build a successful response.
      var resp = {
        bids: []
      };
      var bid = {};

      bid.cmpID = bidReq.params.video.channel_id;
      bid.cpm = adServerKVPs.spotx_bid;
      bid.url = adServerKVPs.spotx_ad_key;
      bid.cur = 'USD';
      bid.bidderCode = 'spotx';
      var sizes = utils.isArray(bidReq.sizes[0]) ? bidReq.sizes[0] : bidReq.sizes;
      bid.height = sizes[1];
      bid.width = sizes[0];
      resp.bids.push(bid);
      KVP_Object = adServerKVPs;
      handleResponse(resp);
    }, function() {
      // No ad...
      handleResponse()
    });
  }

  function createBid(status) {
    var bid = bidfactory.createBid(status, utils.getBidRequest(bidReq.bidId));

    // Stuff we have no matter what
    bid.bidderCode = bidReq.bidder;
    bid.placementCode = bidReq.placementCode;
    bid.requestId = bidReq.requestId;
    bid.code = bidReq.bidder;

    // Stuff we only get with a successful response
    if (status === STATUS.GOOD && KVP_Object) {
      let url = '//search.spotxchange.com/ad/vast.html?key=' + KVP_Object.spotx_ad_key;
      bid.mediaType = 'video';

      bid.cpm = KVP_Object.spotx_bid;
      bid.vastUrl = url;
      bid.spotx_ad_key = KVP_Object.spotx_ad_key;

      var sizes = utils.isArray(bidReq.sizes[0]) ? bidReq.sizes[0] : bidReq.sizes;
      bid.height = sizes[1];
      bid.width = sizes[0];
    }

    return bid;
  }

  /* Notify Prebid of bid responses so bids can get in the auction */
  function handleResponse(response) {
    if (!response || !response.bids || !response.bids.length) {
      bidmanager.addBidResponse(bidReq.placementCode, createBid(STATUS.NO_BID));
    } else {
      bidmanager.addBidResponse(bidReq.placementCode, createBid(STATUS.GOOD, response.bids[0]));
    }
  }

  function validateParams(request) {
    if (typeof request.params !== 'object' && typeof request.params.video !== 'object') {
      return false;
    }

    // Check that all of our required parameters are defined.
    if (bidReq.params.video.channel_id === undefined || bidReq.params.video.slot === undefined || bidReq.params.video.video_slot === undefined) {
      return false;
    }
    return true;
  }

  return Object.assign(this, {
    callBids: baseAdapter.callBids,
    setBidderCode: baseAdapter.setBidderCode
  });
}

adaptermanager.registerBidAdapter(new Spotx(), 'spotx', {
  supportedMediaTypes: ['video']
});

module.exports = Spotx;
<|endoftext|>


<commit_before>var substrat = require('../index'),
    fs = require('fs.extra');

// Test Patterns --------------------------------------------------------------
// ----------------------------------------------------------------------------
var files = [
    'style/main.less',
    'index.jade',
    'js/classes/B.js',
    'partials/form.jade',
    'lib/bootstrap/bootstrap.css',
    'js/classes/C.js',
    'lib/bootstrap/bootstrap.js',
    'js/classes/A.js',
    'lib/bootstrap/bootstrap.min.js',
    'js/app.js',
    'js/util.js',
    'style/fix.less',
    'js/config.js',
    'style/view.less'
];

exports.patterns = {

    fromString: function(test) {

        test.deepEqual(substrat.pattern('*.jade').matches(files), [
            'index.jade'
        ]);

        test.deepEqual(substrat.pattern('js/*.js').matches(files), [
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        test.deepEqual(substrat.pattern('lib/**/*.js').matches(files), [
            'lib/bootstrap/bootstrap.js',
            'lib/bootstrap/bootstrap.min.js'
        ]);

        test.deepEqual(substrat.pattern('style/*.less').matches(files), [
            'style/main.less',
            'style/fix.less',
            'style/view.less'
        ]);

        test.deepEqual(substrat.pattern('js/classes/*').matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js'
        ]);

        test.deepEqual(substrat.pattern('**/*.js').matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'lib/bootstrap/bootstrap.js',
            'js/classes/A.js',
            'lib/bootstrap/bootstrap.min.js',
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        test.done();

    },

    fromRegularExpression: function(test) {

        test.deepEqual(substrat.pattern(/.*\.jade/).matches(files), [
            'index.jade',
            'partials/form.jade'
        ]);

        test.deepEqual(substrat.pattern(/js\/.*\.js/).matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js',
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        test.deepEqual(substrat.pattern(/lib\/.*\/.*\.js/).matches(files), [
            'lib/bootstrap/bootstrap.js',
            'lib/bootstrap/bootstrap.min.js'
        ]);

        test.deepEqual(substrat.pattern(/.*\.js/).matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'lib/bootstrap/bootstrap.js',
            'js/classes/A.js',
            'lib/bootstrap/bootstrap.min.js',
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        test.done();

    },

    fromFunction: function(test) {

        function m(file) {
            return file.indexOf('classes') !== -1;
        }

        test.deepEqual(substrat.pattern(m).matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js'
        ]);

        test.done();

    },

    fromObject: function(test) {

        var obj = {
            string: 'js/*.js',
            regex: /.*\.less$/
        };

        test.deepEqual(substrat.pattern(obj).matches(files), [
            'style/main.less',
            'js/app.js',
            'js/util.js',
            'style/fix.less',
            'js/config.js',
            'style/view.less'
        ]);

        test.done();

    },

    fromArray: function(test) {

        var list = [
            /lib\/.*\.js/,
            'js/classes/*.js',
            /\.js$/
        ];

        test.deepEqual(substrat.pattern(list).matches(files), [
            'lib/bootstrap/bootstrap.js',
            'lib/bootstrap/bootstrap.min.js',
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js',
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        test.done();

    },

    last: function(test) {

        test.deepEqual(substrat.pattern(/\.js$/).last('js/util.js', 'js/config.js', 'js/app.js').matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'lib/bootstrap/bootstrap.js',
            'js/classes/A.js',
            'lib/bootstrap/bootstrap.min.js',
            'js/util.js',
            'js/config.js',
            'js/app.js'
        ]);

        test.done();

    },

    first: function(test) {

        test.deepEqual(substrat.pattern(/\.js$/).first('js/util.js', 'js/config.js', 'js/app.js').matches(files), [
            'js/util.js',
            'js/config.js',
            'js/app.js',
            'js/classes/B.js',
            'js/classes/C.js',
            'lib/bootstrap/bootstrap.js',
            'js/classes/A.js',
            'lib/bootstrap/bootstrap.min.js'
        ]);

        test.done();

    },

    not: function(test) {

        test.deepEqual(substrat.pattern(/\.js$/).not('js/util.js', 'js/config.js', 'js/app.js').matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'lib/bootstrap/bootstrap.js',
            'js/classes/A.js',
            'lib/bootstrap/bootstrap.min.js'
        ]);

        test.done();

    },

    all: function(test) {

        test.deepEqual(substrat.pattern('*').matches(files), [
            'style/main.less',
            'index.jade',
            'js/classes/B.js',
            'partials/form.jade',
            'lib/bootstrap/bootstrap.css',
            'js/classes/C.js',
            'lib/bootstrap/bootstrap.js',
            'js/classes/A.js',
            'lib/bootstrap/bootstrap.min.js',
            'js/app.js',
            'js/util.js',
            'style/fix.less',
            'js/config.js',
            'style/view.less'
        ]);

        test.done();

    },

    multiMatch: function(test) {

        var p = substrat.pattern(/js\/[^\/]*\.js$/, /js\/.*\.js$/);
        test.deepEqual(p.matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js',
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        p = substrat.pattern('js/**/*.js', 'js/*.js');
        test.deepEqual(p.matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js',
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        test.done();

    },

    combination: function(test) {

        var p = substrat.pattern(/js\/.*\.js$/).
                first('js/config.js').
                last('js/classes/**/*.js', 'js/util.js', 'js/app.js');

        test.deepEqual(p.matches(files), [
            'js/config.js',
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js',
            'js/util.js',
            'js/app.js'
        ]);

        test.done();

    }

};

function run(test, tasks, callback) {

    var sub = substrat.init({
        src: 'test/src',
        dest: 'test/public',
        quiet: true,
        tasks: tasks || []
    });

    fs.rmdir('./test/public', function(err) {

        sub.once('done', function() {

            var files = null,
                data = null;

            try {
                files = fs.readdirSync('test/public');
                data = new Array(files.length);
                files.forEach(function(file, index) {
                    data[index] = fs.readFileSync('test/public/' + file).toString();
                });

            } catch(e) {
                files = [];
                data = [];
            }

            try {
                callback(files.sort(), data);
                test.done();

            } catch(err) {
                test.fail(err);
            }

        });

        sub.run();

    });

    return sub;

}

exports.substrat = {

    init: function(test) {

        var sub = run(test, null, function() {
            test.strictEqual(typeof sub.run, 'function');
            test.strictEqual(typeof sub.watch, 'function');
            test.strictEqual(typeof sub.listen, 'function');
            test.strictEqual(typeof sub.stop, 'function');
            test.strictEqual(typeof sub.pattern, 'function');
            test.strictEqual(typeof sub.files, 'function');
        });

    }

};

exports.tasks = {

    compile: function(test) {

        var tasks = [
            substrat.task.compile(/\.js$/, 'js'),
            substrat.task.compile(/\.jade$/, 'jade'),
            substrat.task.compile(/\.less$/, 'less')
        ];

        run(test, tasks, function(files, data) {

            test.deepEqual(files, ['test.css', 'test.html', 'test.js']);
            test.deepEqual(data, [
                '#test {\n  color: #ff0000;\n}\n.test {\n  color: #ff0000;\n}\n/*# sourceMappingURL=data:application/json,%7B%22version%22%3A3%2C%22sources%22%3A%5B%22test.less%22%5D%2C%22names%22%3A%5B%5D%2C%22mappings%22%3A%22AAEM%3BEACF%2CcAAA%3B%3BAAGE%3BEACF%2CcAAA%22%7D */',
                '\n\n  \n  \n',
                'function test(foo, bar) {\n    return foo + bar + 2;\n}\n'
            ]);

        });

    },

    concat: function(test) {

        var tasks = [
            substrat.task.concat(/\.js$/, 'js', 'all.js'),
            substrat.task.concat(/\.less$/, 'less', 'all.css')
        ];

        run(test, tasks, function(files, data) {

            test.deepEqual(files, ['all.css', 'all.js']);
            test.deepEqual(data, [
                '#test {\n  color: #ff0000;\n}\n.test {\n  color: #ff0000;\n}\n/*# sourceMappingURL=data:application/json,%7B%22version%22%3A3%2C%22sources%22%3A%5B%22input%22%5D%2C%22names%22%3A%5B%5D%2C%22mappings%22%3A%22AAEM%3BEACF%2CcAAA%3B%3BAAGE%3BEACF%2CcAAA%22%7D */',
                'function test(foo, bar) {\n    return foo + bar + 2;\n}\n'
            ]);

        });

    },

    copy: function(test) {

        var tasks = [
            substrat.task.copy('*')
        ];

        run(test, tasks, function(files, data) {

            test.deepEqual(files, [
                'test.jade',
                'test.js',
                'test.json',
                'test.less',
                'test.md'
            ]);

            test.deepEqual(data, [
                'html\n  head\n\n  body\n',
                'function test(foo, bar) {\n    return foo + bar + 2;\n}\n',
                '{\n    "string": \'"{{{String}}}"\',\n    "object": "{{{Object}}}"\n}\n',
                '@red: #ff0000;\n\n#test {\n    color: @red;\n}\n\n.test {\n    color: @red;\n}\n\n',
                '## Test\n\nTest.\n'
            ]);

        });

    },

    template: function(test) {

        var tasks = [
            substrat.task.template('test.json', {
                Object: JSON.stringify({
                    test: 'test'
                }),
                String: 'Test'

            }, ['"{{', '}}"'])
        ];

        run(test, tasks, function(files, data) {

            test.deepEqual(data, [
                '{\n    "string": \'Test\',\n    "object": {"test":"test"}\n}\n'
            ]);
            test.deepEqual(files, ['test.json']);

        });

    }

};

<commit_msg>Make sure to sort files in tests to avoid issues with different file orderd coming back from fs.readdir<commit_after>var substrat = require('../index'),
    fs = require('fs.extra');

// Test Patterns --------------------------------------------------------------
// ----------------------------------------------------------------------------
var files = [
    'style/main.less',
    'index.jade',
    'js/classes/B.js',
    'partials/form.jade',
    'lib/bootstrap/bootstrap.css',
    'js/classes/C.js',
    'lib/bootstrap/bootstrap.js',
    'js/classes/A.js',
    'lib/bootstrap/bootstrap.min.js',
    'js/app.js',
    'js/util.js',
    'style/fix.less',
    'js/config.js',
    'style/view.less'
];

exports.patterns = {

    fromString: function(test) {

        test.deepEqual(substrat.pattern('*.jade').matches(files), [
            'index.jade'
        ]);

        test.deepEqual(substrat.pattern('js/*.js').matches(files), [
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        test.deepEqual(substrat.pattern('lib/**/*.js').matches(files), [
            'lib/bootstrap/bootstrap.js',
            'lib/bootstrap/bootstrap.min.js'
        ]);

        test.deepEqual(substrat.pattern('style/*.less').matches(files), [
            'style/main.less',
            'style/fix.less',
            'style/view.less'
        ]);

        test.deepEqual(substrat.pattern('js/classes/*').matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js'
        ]);

        test.deepEqual(substrat.pattern('**/*.js').matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'lib/bootstrap/bootstrap.js',
            'js/classes/A.js',
            'lib/bootstrap/bootstrap.min.js',
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        test.done();

    },

    fromRegularExpression: function(test) {

        test.deepEqual(substrat.pattern(/.*\.jade/).matches(files), [
            'index.jade',
            'partials/form.jade'
        ]);

        test.deepEqual(substrat.pattern(/js\/.*\.js/).matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js',
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        test.deepEqual(substrat.pattern(/lib\/.*\/.*\.js/).matches(files), [
            'lib/bootstrap/bootstrap.js',
            'lib/bootstrap/bootstrap.min.js'
        ]);

        test.deepEqual(substrat.pattern(/.*\.js/).matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'lib/bootstrap/bootstrap.js',
            'js/classes/A.js',
            'lib/bootstrap/bootstrap.min.js',
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        test.done();

    },

    fromFunction: function(test) {

        function m(file) {
            return file.indexOf('classes') !== -1;
        }

        test.deepEqual(substrat.pattern(m).matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js'
        ]);

        test.done();

    },

    fromObject: function(test) {

        var obj = {
            string: 'js/*.js',
            regex: /.*\.less$/
        };

        test.deepEqual(substrat.pattern(obj).matches(files), [
            'style/main.less',
            'js/app.js',
            'js/util.js',
            'style/fix.less',
            'js/config.js',
            'style/view.less'
        ]);

        test.done();

    },

    fromArray: function(test) {

        var list = [
            /lib\/.*\.js/,
            'js/classes/*.js',
            /\.js$/
        ];

        test.deepEqual(substrat.pattern(list).matches(files), [
            'lib/bootstrap/bootstrap.js',
            'lib/bootstrap/bootstrap.min.js',
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js',
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        test.done();

    },

    last: function(test) {

        test.deepEqual(substrat.pattern(/\.js$/).last('js/util.js', 'js/config.js', 'js/app.js').matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'lib/bootstrap/bootstrap.js',
            'js/classes/A.js',
            'lib/bootstrap/bootstrap.min.js',
            'js/util.js',
            'js/config.js',
            'js/app.js'
        ]);

        test.done();

    },

    first: function(test) {

        test.deepEqual(substrat.pattern(/\.js$/).first('js/util.js', 'js/config.js', 'js/app.js').matches(files), [
            'js/util.js',
            'js/config.js',
            'js/app.js',
            'js/classes/B.js',
            'js/classes/C.js',
            'lib/bootstrap/bootstrap.js',
            'js/classes/A.js',
            'lib/bootstrap/bootstrap.min.js'
        ]);

        test.done();

    },

    not: function(test) {

        test.deepEqual(substrat.pattern(/\.js$/).not('js/util.js', 'js/config.js', 'js/app.js').matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'lib/bootstrap/bootstrap.js',
            'js/classes/A.js',
            'lib/bootstrap/bootstrap.min.js'
        ]);

        test.done();

    },

    all: function(test) {

        test.deepEqual(substrat.pattern('*').matches(files), [
            'style/main.less',
            'index.jade',
            'js/classes/B.js',
            'partials/form.jade',
            'lib/bootstrap/bootstrap.css',
            'js/classes/C.js',
            'lib/bootstrap/bootstrap.js',
            'js/classes/A.js',
            'lib/bootstrap/bootstrap.min.js',
            'js/app.js',
            'js/util.js',
            'style/fix.less',
            'js/config.js',
            'style/view.less'
        ]);

        test.done();

    },

    multiMatch: function(test) {

        var p = substrat.pattern(/js\/[^\/]*\.js$/, /js\/.*\.js$/);
        test.deepEqual(p.matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js',
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        p = substrat.pattern('js/**/*.js', 'js/*.js');
        test.deepEqual(p.matches(files), [
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js',
            'js/app.js',
            'js/util.js',
            'js/config.js'
        ]);

        test.done();

    },

    combination: function(test) {

        var p = substrat.pattern(/js\/.*\.js$/).
                first('js/config.js').
                last('js/classes/**/*.js', 'js/util.js', 'js/app.js');

        test.deepEqual(p.matches(files), [
            'js/config.js',
            'js/classes/B.js',
            'js/classes/C.js',
            'js/classes/A.js',
            'js/util.js',
            'js/app.js'
        ]);

        test.done();

    }

};

function run(test, tasks, callback) {

    var sub = substrat.init({
        src: 'test/src',
        dest: 'test/public',
        quiet: true,
        tasks: tasks || []
    });

    fs.rmdir('./test/public', function(err) {

        sub.once('done', function() {

            var files = null,
                data = null;

            try {
                files = fs.readdirSync('test/public').sort();
                data = new Array(files.length);
                files.forEach(function(file, index) {
                    data[index] = fs.readFileSync('test/public/' + file).toString();
                });

            } catch(e) {
                files = [];
                data = [];
            }

            try {
                callback(files, data);
                test.done();

            } catch(err) {
                test.fail(err);
            }

        });

        sub.run();

    });

    return sub;

}

exports.substrat = {

    init: function(test) {

        var sub = run(test, null, function() {
            test.strictEqual(typeof sub.run, 'function');
            test.strictEqual(typeof sub.watch, 'function');
            test.strictEqual(typeof sub.listen, 'function');
            test.strictEqual(typeof sub.stop, 'function');
            test.strictEqual(typeof sub.pattern, 'function');
            test.strictEqual(typeof sub.files, 'function');
        });

    }

};

exports.tasks = {

    compile: function(test) {

        var tasks = [
            substrat.task.compile(/\.js$/, 'js'),
            substrat.task.compile(/\.jade$/, 'jade'),
            substrat.task.compile(/\.less$/, 'less')
        ];

        run(test, tasks, function(files, data) {

            test.deepEqual(files, ['test.css', 'test.html', 'test.js']);
            test.deepEqual(data, [
                '#test {\n  color: #ff0000;\n}\n.test {\n  color: #ff0000;\n}\n/*# sourceMappingURL=data:application/json,%7B%22version%22%3A3%2C%22sources%22%3A%5B%22test.less%22%5D%2C%22names%22%3A%5B%5D%2C%22mappings%22%3A%22AAEM%3BEACF%2CcAAA%3B%3BAAGE%3BEACF%2CcAAA%22%7D */',
                '\n\n  \n  \n',
                'function test(foo, bar) {\n    return foo + bar + 2;\n}\n'
            ]);

        });

    },

    concat: function(test) {

        var tasks = [
            substrat.task.concat(/\.js$/, 'js', 'all.js'),
            substrat.task.concat(/\.less$/, 'less', 'all.css')
        ];

        run(test, tasks, function(files, data) {

            test.deepEqual(files, ['all.css', 'all.js']);
            test.deepEqual(data, [
                '#test {\n  color: #ff0000;\n}\n.test {\n  color: #ff0000;\n}\n/*# sourceMappingURL=data:application/json,%7B%22version%22%3A3%2C%22sources%22%3A%5B%22input%22%5D%2C%22names%22%3A%5B%5D%2C%22mappings%22%3A%22AAEM%3BEACF%2CcAAA%3B%3BAAGE%3BEACF%2CcAAA%22%7D */',
                'function test(foo, bar) {\n    return foo + bar + 2;\n}\n'
            ]);

        });

    },

    copy: function(test) {

        var tasks = [
            substrat.task.copy('*')
        ];

        run(test, tasks, function(files, data) {

            test.deepEqual(files, [
                'test.jade',
                'test.js',
                'test.json',
                'test.less',
                'test.md'
            ]);

            test.deepEqual(data, [
                'html\n  head\n\n  body\n',
                'function test(foo, bar) {\n    return foo + bar + 2;\n}\n',
                '{\n    "string": \'"{{{String}}}"\',\n    "object": "{{{Object}}}"\n}\n',
                '@red: #ff0000;\n\n#test {\n    color: @red;\n}\n\n.test {\n    color: @red;\n}\n\n',
                '## Test\n\nTest.\n'
            ]);

        });

    },

    template: function(test) {

        var tasks = [
            substrat.task.template('test.json', {
                Object: JSON.stringify({
                    test: 'test'
                }),
                String: 'Test'

            }, ['"{{', '}}"'])
        ];

        run(test, tasks, function(files, data) {

            test.deepEqual(data, [
                '{\n    "string": \'Test\',\n    "object": {"test":"test"}\n}\n'
            ]);
            test.deepEqual(files, ['test.json']);

        });

    }

};

<|endoftext|>


<commit_before>
/**
 * socket.io
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

(function (exports, io) {

  /**
   * Expose constructor.
   */

  exports.websocket = WS;

  /**
   * The WebSocket transport uses the HTML5 WebSocket API to establish an persistent
   * connection with the Socket.IO server. This transport will also be inherited by the
   * FlashSocket fallback as it provides a API compatible polyfill for the WebSockets.
   *
   * @constructor
   * @extends {io.Transport}
   * @api public
   */

  function WS (socket) {
    io.Transport.apply(this, arguments);
  };

  /**
   * Inherits from Transport.
   */

  io.util.inherit(WS, io.Transport);

  /**
   * Transport name
   *
   * @api public
   */

  WS.prototype.name = 'websocket';

  /**
   * Initializes a new `WebSocket` connection with the Socket.IO server. We attach
   * all the appropriate listeners to handle the responses from the server.
   *
   * @returns {Transport}
   * @api public
   */

  WS.prototype.open = function(){
    this.websocket = new WebSocket(this.prepareUrl());

    var self = this;
    this.websocket.onopen = function () {
      self.onOpen();
      self.socket.setBuffer(false);
    };
    this.websocket.onmessage = function (ev) {
      self.onData(ev.data);
    };
    this.websocket.onclose = function () {
      self.onClose();
      self.socket.setBuffer(true);
    };
    this.websocket.onerror = function (e) {
      self.onError(e);
    };

    return this;
  };

  /**
   * Send a message to the Socket.IO server. The message will automatically be encoded
   * in the correct message format.
   *
   * @returns {Transport}
   * @api public
   */

  WS.prototype.send = function (data) {
    this.websocket.send(data);
    return this;
  };

  /**
   * Disconnect the established `WebSocket` connection.
   *
   * @returns {Transport}
   * @api public
   */

  WS.prototype.close = function(){
    this.websocket.close();
    return this;
  };

  /**
   * Handle the errors that `WebSocket` might be giving when we
   * are attempting to connect or send messages.
   *
   * @param {Error} e The error.
   * @api private
   */

  WS.prototype.onError = function(e){
    this.socket.onError(e);
  };

  /**
   * Returns the appropriate scheme for the URI generation.
   *
   * @api private
   */
  WS.prototype.scheme = function(){
    return (this.socket.options.secure ? 'wss' : 'ws');
  };

  /**
   * Checks if the browser has support for native `WebSockets` and that
   * it's not the polyfill created for the FlashSocket transport.
   *
   * @return {Boolean}
   * @api public
   */

  WS.check = function(){
    return 'WebSocket' in window && !('__addTask' in WebSocket);
  };

  /**
   * Check if the `WebSocket` transport support cross domain communications.
   *
   * @returns {Boolean}
   * @api public
   */

  WS.xdomainCheck = function(){
    return true;
  };

  /**
   * Add the transport to your public io.transports array.
   *
   * @api private
   */

  io.transports.push('websocket');

})(
    'undefined' != typeof io ? io.Transport : module.exports
  , 'undefined' != typeof io ? io : module.parent.exports
);
<commit_msg>Implemented `WebSocket#payload`, to avoid artificial framing on top of the WebSocket protocol.<commit_after>
/**
 * socket.io
 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

(function (exports, io) {

  /**
   * Expose constructor.
   */

  exports.websocket = WS;

  /**
   * The WebSocket transport uses the HTML5 WebSocket API to establish an persistent
   * connection with the Socket.IO server. This transport will also be inherited by the
   * FlashSocket fallback as it provides a API compatible polyfill for the WebSockets.
   *
   * @constructor
   * @extends {io.Transport}
   * @api public
   */

  function WS (socket) {
    io.Transport.apply(this, arguments);
  };

  /**
   * Inherits from Transport.
   */

  io.util.inherit(WS, io.Transport);

  /**
   * Transport name
   *
   * @api public
   */

  WS.prototype.name = 'websocket';

  /**
   * Initializes a new `WebSocket` connection with the Socket.IO server. We attach
   * all the appropriate listeners to handle the responses from the server.
   *
   * @returns {Transport}
   * @api public
   */

  WS.prototype.open = function(){
    this.websocket = new WebSocket(this.prepareUrl());

    var self = this;
    this.websocket.onopen = function () {
      self.onOpen();
      self.socket.setBuffer(false);
    };
    this.websocket.onmessage = function (ev) {
      self.onData(ev.data);
    };
    this.websocket.onclose = function () {
      self.onClose();
      self.socket.setBuffer(true);
    };
    this.websocket.onerror = function (e) {
      self.onError(e);
    };

    return this;
  };

  /**
   * Send a message to the Socket.IO server. The message will automatically be encoded
   * in the correct message format.
   *
   * @returns {Transport}
   * @api public
   */

  WS.prototype.send = function (data) {
    this.websocket.send(data);
    return this;
  };

  /**
   * Payload
   *
   * @api private
   */

  WS.prototype.payload = function (arr) {
    for (var i = 0, l = arr.length; i < l; i++) {
      this.packet(arr[i]);
    }
    return this;
  };

  /**
   * Disconnect the established `WebSocket` connection.
   *
   * @returns {Transport}
   * @api public
   */

  WS.prototype.close = function(){
    this.websocket.close();
    return this;
  };

  /**
   * Handle the errors that `WebSocket` might be giving when we
   * are attempting to connect or send messages.
   *
   * @param {Error} e The error.
   * @api private
   */

  WS.prototype.onError = function(e){
    this.socket.onError(e);
  };

  /**
   * Returns the appropriate scheme for the URI generation.
   *
   * @api private
   */
  WS.prototype.scheme = function(){
    return (this.socket.options.secure ? 'wss' : 'ws');
  };

  /**
   * Checks if the browser has support for native `WebSockets` and that
   * it's not the polyfill created for the FlashSocket transport.
   *
   * @return {Boolean}
   * @api public
   */

  WS.check = function(){
    return 'WebSocket' in window && !('__addTask' in WebSocket);
  };

  /**
   * Check if the `WebSocket` transport support cross domain communications.
   *
   * @returns {Boolean}
   * @api public
   */

  WS.xdomainCheck = function(){
    return true;
  };

  /**
   * Add the transport to your public io.transports array.
   *
   * @api private
   */

  io.transports.push('websocket');

})(
    'undefined' != typeof io ? io.Transport : module.exports
  , 'undefined' != typeof io ? io : module.parent.exports
);
<|endoftext|>