<commit_before>var robohornet = {};

/**
 * Benchmark version.
 *
 * @type {string}
 */
robohornet.BENCHMARK_VERSION = 'RH100';

/**
 * Class representing a the RoboHornet test runner.
 *
 * @param {Array.<Object>} benchmarkDetails Array of benchmark json objects.
 * @constructor
 */
robohornet.Runner = function(benchmarkDetails) {
  this.testFrame = document.getElementById('testFrame');
  this.testsContainer = document.getElementById('tests');
  this.statusElement_ = document.getElementById('status');
  this.scoreElement_ = document.getElementById('score');
  this.runElement_ = document.getElementById('runButton');
  var benchmark;
  var benchmarks = [];
  var benchmarksMap = {};
  for (var details, i = 0; details = benchmarkDetails[i]; i++) {
    benchmark = new robohornet.Benchmark(this, details)
    benchmarks.push(benchmark);
    benchmarksMap[benchmark.id] = benchmark;
  }
  this.benchmarks_ = benchmarks;
  this.benchmarksMap_ = benchmarksMap;
  this.currentIndex_ = -1;
  this.overallScore_ = 0;
  this.benchmarkCount_ = 0;
  this.benchmarksRun_ = 0;
};

(function() {
  var _p = robohornet.Runner.prototype;

  _p.init = function() {
    var totalWeight = 0;
    for (var benchmark, i = 0; benchmark = this.benchmarks_[i]; i++) {
      totalWeight += benchmark.weight;
    }
    for (var benchmark, i = 0; benchmark = this.benchmarks_[i]; i++) {
      benchmark.computedWeight = (benchmark.weight / totalWeight) * 100;
      benchmark.index = i;
      benchmark.register();
    }
    this.benchmarkCount_ = this.benchmarks_.length;
    this.digestHash_();
    this.runElement_.disabled = false;
    this.setStatus_('Ready');
  };

  _p.run = function() {
    this.currentIndex_ = -1;
    this.overallScore_ = 0;
    this.setStatus_('Running...');
    this.scoreElement_.textContent = '';
    var message = document.createElement('em');
    message.appendChild(document.createTextNode('Please wait...'));
    this.scoreElement_.appendChild(message);
    this.runElement_.disabled = true;
    for (var benchmark, i = 0; benchmark = this.benchmarks_[i]; i++) {
      var identifier = 'benchmark-' + benchmark.index;
      document.getElementById(identifier + '-toggle').disabled = true;
      benchmark.setStatus_('Waiting...');
    }
    this.benchmarksRun_ = 0;
    this.next_();
  };

  _p.benchmarkSucceeded = function() {
    this.benchmarksRun_++;
    this.next_();
  }

  _p.benchmarkSkipped = function() {
    this.next_();
  }

  _p.next_ = function() {
     if (++this.currentIndex_ < this.benchmarks_.length) {
       this.benchmarks_[this.currentIndex_].load();
    } else
      this.done_();
  };

  _p.incrementOverallScore = function(score) {
    this.overallScore_ += score;
  }

  _p.done_ = function() {
    this.testFrame.src = 'javascript:void(0)';
    this.scoreElement_.textContent = '';
    if (this.benchmarksRun_ == this.benchmarkCount_) {
      var version = document.createElement('span');
      version.className = 'version';
      version.appendChild(document.createTextNode(
          robohornet.BENCHMARK_VERSION));
      this.scoreElement_.appendChild(version);
      var score = document.createElement('span');
      score.appendChild(document.createTextNode(
          Math.round(this.overallScore_ * 100) / 100));
      this.scoreElement_.appendChild(score);
    } else {
      var message = document.createElement('em');
      message.appendChild(document.createTextNode(
          'Enable all tests to see the score'));
      this.scoreElement_.appendChild(message);
    }
    this.runElement_.disabled = false;
    for (var benchmark, i = 0; benchmark = this.benchmarks_[i]; i++) {
      var identifier = 'benchmark-' + benchmark.index;
      document.getElementById(identifier + '-toggle').disabled = false;
    }

    this.setStatus_('Ran ' + this.benchmarksRun_ + ' out of ' +
        this.benchmarkCount_ + ' benchmarks.');
  };

  _p.setStatus_ = function(textContent) {
    this.statusElement_.textContent = textContent;
  };

  _p.updateHash = function() {
    var disabledBenchmarkIDs = [];
    for (var benchmark, i = 0; benchmark = this.benchmarks_[i]; i++) {
      if (!benchmark.enabled)
        disabledBenchmarkIDs.push(benchmark.id);
    }
    if (disabledBenchmarkIDs.length) {
      window.location.hash = "#d=" + disabledBenchmarkIDs.join(",");
    } else {
      window.location.hash = "";
    }
  }

  _p.digestHash_ = function() {
    var hash = window.location.hash;
    if (!hash)
      return;
    hash = hash.replace("#", "").toLowerCase().split("&");
    for (var segment, i = 0; segment = hash[i]; i++) {
      hash[i] = hash[i].split("=");
      switch (hash[i][0]) {
        case "d":
          var ids = hash[i][1].split(",");
          for (var benchmarkID, j = 0; benchmarkID = ids[j]; j++) {
            var benchmark = this.benchmarksMap_[benchmarkID];
            if (!benchmark)
              continue;
            benchmark.setEnabled(false, true);
          }
          break;
      }
    }
  }
})();

/**
 * Class representing a single benchmark.
 *
 * @param {robohornet.Runner} runner Test runner instance.
 * @param {Object} details Benchmarks details as json object.
 * @constructor
 */
robohornet.Benchmark = function(runner, details) {
  this.runner = runner;
  if (!details) details = {};
  this.name = details.name;
  this.description = details.description;
  this.filename = details.filename;
  this.runs = details.runs;
  this.weight = details.weight;
  this.baselineTime = details.baselineTime;

  this.id = this.filename.match(/\/([A-z]+)\./)[1].toLowerCase();

  this.loadCallback_ = bind(this.onFrameLoaded_, this);
  this.errorCallback_ = bind(this.onFrameError_, this);
  this.toggleCallback_ = bind(this.enabledClicked_, this);
};

(function() {
  var _p = robohornet.Benchmark.prototype;

  _p.addCell_ = function(rowElement, textContent, opt_className) {
    var cell = document.createElement('td');
    if (opt_className)
      cell.className = opt_className;
    cell.appendChild(document.createTextNode(textContent));
    rowElement.appendChild(cell);
  };

  _p.register = function() {
    var identifier = 'benchmark-' + this.index;

    // Append summary row.
    var row = document.createElement('tr');
    row.id = identifier;
    var cell = document.createElement('td');
    var checkbox = document.createElement('input');
    checkbox.type = 'checkbox';
    checkbox.id = identifier + '-toggle';
    checkbox.checked = true;
    this.toggleElement_ = checkbox;
    this.toggleElement_.addEventListener('click', this.toggleCallback_, false);
    cell.appendChild(checkbox);

    var label = document.createElement('label');
    label.htmlFor = checkbox.id;
    label.appendChild(document.createTextNode(this.name));
    cell.appendChild(label);

    row.appendChild(cell);

    this.addCell_(row, '-');
    this.addCell_(row, '-', 'number');
    this.addCell_(row, this.baselineTime.toFixed(2) + 'ms', 'number');
    this.addCell_(row, this.computedWeight.toFixed(2) + '%', 'number');
    this.addCell_(row, '-', 'number');
    this.runner.testsContainer.tBodies[0].appendChild(row);
    this.rowElement_ = row;

    // Append details row.
    row = document.createElement('tr');
    cell = document.createElement('td');
    cell.className = 'details';
    cell.colSpan = 2;

    var detailsElement = document.createElement('div');
    detailsElement.className = 'details-container';
    cell.appendChild(detailsElement);
    detailsElement.appendChild(document.createTextNode(this.description));

    // Append list of runs/parameters.
    var runsTable = document.createElement('table');
    runsTable.id = identifier + '-runs';
    runsTable.className = 'runs';
    runsTable.appendChild(document.createElement('thead'));

    var headerRow = document.createElement('tr');
    this.addCell_(headerRow, 'Parameters');
    this.addCell_(headerRow, 'Runs', 'number');
    this.addCell_(headerRow, 'Error', 'number');
    this.addCell_(headerRow, 'Mean', 'number');
    runsTable.tHead.appendChild(headerRow);

    runsTable.appendChild(document.createElement('tbody'));
    for (var i = 0; i < this.runs.length; i++) {
      var runsRow = document.createElement('tr');
      this.addCell_(runsRow, this.runs[i][0], 'name');
      this.addCell_(runsRow, '0', 'number');
      this.addCell_(runsRow, '0', 'number');
      this.addCell_(runsRow, '0', 'number');
      runsTable.tBodies[0].appendChild(runsRow);
    }
    detailsElement.appendChild(runsTable);

    this.detailsElement_ = detailsElement;
    this.onToggle_();

    row.appendChild(cell);
    this.runner.testsContainer.tBodies[0].appendChild(row);
  };

  _p.enabledClicked_ = function() {
    this.onToggle_();
    this.runner.updateHash();
  }

  _p.setEnabled = function(enabled, opt_skipUpdateHash) {
    this.toggleElement_.checked = enabled;
    this.onToggle_();
    if (!opt_skipUpdateHash)
      this.runner.updateHash();
  }

  _p.onToggle_ = function() {
    this.enabled = this.toggleElement_.checked;
    this.detailsElement_.className = 'details-container ' + (this.enabled ?
        'enabled' : 'disabled');
  };

  _p.load = function() {
    if (!this.enabled) {
      this.setStatus_('Skipped');
      this.runner.benchmarkSkipped();
      return;
    }

    this.runner.testFrame.addEventListener('load', this.loadCallback_, false);
    this.runner.testFrame.addEventListener('error', this.errorCallback_, false);

    this.setStatus_('Loading...');
    this.runner.testFrame.src = this.filename;
  };

  _p.onComplete_ = function(suite) {
    var results = [];
    for (var run, i = 0; run = suite[i]; i++) {
      results.push({
        name: run.name,
        mean: run.stats.mean * 1000,
        rme: run.stats.RME,
        runs: run.stats.size
      });
    }
    this.setResults(results);
    this.runner.benchmarkSucceeded();
  };

  _p.onFrameLoaded_ = function() {
    this.removeListeners_();

    var win = this.runner.testFrame.contentWindow;
    if (!win.test) {
      this.setStatus_('Invalid file.');
      this.runner.benchmarkSkipped();
      return;
    }

    var self = this;
    var suite = new Benchmark.Suite(this.name, {
      onComplete: function() { self.onComplete_(this); }
    });

    for (var run, i = 0; run = this.runs[i]; i++) {
      var argument = run[1];
      suite.add(run[0], bind(win.test, win, argument), {
        setup: bind(win.setUp, win, argument),
        teardown: bind(win.tearDown, win, argument)
      });
    }

    this.setStatus_('Running...');
    suite.run(true);
  };

  _p.onFrameError_ = function() {
    this.removeListeners_();
    this.setStatus_('Unable to load file.');
    this.runner.benchmarkSkipped();
  };

  _p.removeListeners_ = function() {
    this.runner.testFrame.removeEventListener('load', this.loadCallback_,
        false);
    this.runner.testFrame.removeEventListener('error', this.errorCallback_,
        false);
  };

  _p.setResults = function(results) {
    var row = this.rowElement_;
    row.cells[1].textContent = 'Computing Score...';

    var accumulatedMean = 0;
    var runsTable = document.getElementById(row.id + '-runs');
    for (var result, i = 0; result = results[i]; i++) {
      var runCells = runsTable.tBodies[0].rows[i].cells;
      runCells[1].textContent = result.runs;
      runCells[2].textContent = String.fromCharCode(177) +
          result.rme.toFixed(2) + '%';
      runCells[3].textContent = result.mean.toFixed(2) + 'ms';
      accumulatedMean += result.mean;
    }

    var diff = accumulatedMean - this.baselineTime;
    var score = this.baselineTime * this.computedWeight / accumulatedMean;
    this.runner.incrementOverallScore(score);

    row.cells[1].textContent = 'Completed successfully ';
    row.cells[2].textContent = accumulatedMean.toFixed(2) + 'ms';
    row.cells[5].textContent = score.toFixed(2);
  };

  _p.setStatus_ = function(statusText) {
    var row = this.rowElement_;
    row.cells[1].textContent = statusText;
  };
})();

function bind(fn, opt_scope, var_args) {
  var scope = opt_scope || window;
  var len = arguments.length;
  var args = [];
  for (var i = 2; i < len; i++) {
  args.push(arguments[i]);
  }
  return function() {
  fn.apply(scope, args);
  };
}
<commit_msg>When all of the tests fail we show a message to the user reminding them that to run RoboHornet locally on Chrome you need to use the --allow-file-access-from-files flag.<commit_after>var robohornet = {};

/**
 * Benchmark version.
 *
 * @type {string}
 */
robohornet.BENCHMARK_VERSION = 'RH100';

/**
 * Class representing a the RoboHornet test runner.
 *
 * @param {Array.<Object>} benchmarkDetails Array of benchmark json objects.
 * @constructor
 */
robohornet.Runner = function(benchmarkDetails) {
  this.testFrame = document.getElementById('testFrame');
  this.testsContainer = document.getElementById('tests');
  this.statusElement_ = document.getElementById('status');
  this.scoreElement_ = document.getElementById('score');
  this.runElement_ = document.getElementById('runButton');
  var benchmark;
  var benchmarks = [];
  var benchmarksMap = {};
  for (var details, i = 0; details = benchmarkDetails[i]; i++) {
    benchmark = new robohornet.Benchmark(this, details);
    benchmarks.push(benchmark);
    benchmarksMap[benchmark.id] = benchmark;
  }
  this.benchmarks_ = benchmarks;
  this.benchmarksMap_ = benchmarksMap;
  this.currentIndex_ = -1;
  this.overallScore_ = 0;
  this.benchmarkCount_ = 0;
  this.benchmarksRun_ = 0;
  this.benchmarksFailed_ = 0;
};

(function() {
  var _p = robohornet.Runner.prototype;

  _p.init = function() {
    var totalWeight = 0;
    for (var benchmark, i = 0; benchmark = this.benchmarks_[i]; i++) {
      totalWeight += benchmark.weight;
    }
    for (var benchmark, i = 0; benchmark = this.benchmarks_[i]; i++) {
      benchmark.computedWeight = (benchmark.weight / totalWeight) * 100;
      benchmark.index = i;
      benchmark.register();
    }
    this.benchmarkCount_ = this.benchmarks_.length;
    this.digestHash_();
    this.runElement_.disabled = false;
    this.setStatus_('Ready');
  };

  _p.run = function() {
    this.currentIndex_ = -1;
    this.overallScore_ = 0;
    this.setStatus_('Running...');
    this.scoreElement_.textContent = '';
    var message = document.createElement('em');
    message.appendChild(document.createTextNode('Please wait...'));
    this.scoreElement_.appendChild(message);
    this.runElement_.disabled = true;
    for (var benchmark, i = 0; benchmark = this.benchmarks_[i]; i++) {
      var identifier = 'benchmark-' + benchmark.index;
      document.getElementById(identifier + '-toggle').disabled = true;
      benchmark.setStatus_('Waiting...');
    }
    this.benchmarksRun_ = 0;
    this.benchmarksFailed_ = 0;
    this.next_();
  };

  _p.benchmarkSucceeded = function() {
    this.benchmarksRun_++;
    this.next_();
  }

  _p.benchmarkSkipped = function(failed) {
    if (failed)
      this.benchmarksFailed_++;
    this.next_();
  }

  _p.next_ = function() {
     if (++this.currentIndex_ < this.benchmarks_.length) {
       this.benchmarks_[this.currentIndex_].load();
    } else
      this.done_();
  };

  _p.incrementOverallScore = function(score) {
    this.overallScore_ += score;
  }

  _p.done_ = function() {
    this.testFrame.src = 'javascript:void(0)';
    this.scoreElement_.textContent = '';
    if (this.benchmarksRun_ == this.benchmarkCount_) {
      var version = document.createElement('span');
      version.className = 'version';
      version.appendChild(document.createTextNode(
          robohornet.BENCHMARK_VERSION));
      this.scoreElement_.appendChild(version);
      var score = document.createElement('span');
      score.appendChild(document.createTextNode(
          Math.round(this.overallScore_ * 100) / 100));
      this.scoreElement_.appendChild(score);
    } else if (this.benchmarksFailed_ == this.benchmarkCount_) {
      var message = document.createElement('em');
      message.appendChild(document.createTextNode(
          'Test failed'));
      this.scoreElement_.appendChild(message);
      alert('To run RoboHornet locally you need to run Chrome with the --allow-file-access-from-files flag.');
    } else {
      var message = document.createElement('em');
      message.appendChild(document.createTextNode(
          'Enable all tests to see the score'));
      this.scoreElement_.appendChild(message);
    }
    this.runElement_.disabled = false;
    for (var benchmark, i = 0; benchmark = this.benchmarks_[i]; i++) {
      var identifier = 'benchmark-' + benchmark.index;
      document.getElementById(identifier + '-toggle').disabled = false;
    }

    this.setStatus_('Ran ' + this.benchmarksRun_ + ' out of ' +
        this.benchmarkCount_ + ' benchmarks.');
  };

  _p.setStatus_ = function(textContent) {
    this.statusElement_.textContent = textContent;
  };

  _p.updateHash = function() {
    var disabledBenchmarkIDs = [];
    for (var benchmark, i = 0; benchmark = this.benchmarks_[i]; i++) {
      if (!benchmark.enabled)
        disabledBenchmarkIDs.push(benchmark.id);
    }
    if (disabledBenchmarkIDs.length) {
      window.location.hash = '#d=' + disabledBenchmarkIDs.join(',');
    } else {
      window.location.hash = '';
    }
  }

  _p.digestHash_ = function() {
    var hash = window.location.hash;
    if (!hash)
      return;
    hash = hash.replace('#', '').toLowerCase().split('&');
    for (var segment, i = 0; segment = hash[i]; i++) {
      hash[i] = hash[i].split('=');
      switch (hash[i][0]) {
        case 'd':
          var ids = hash[i][1].split(',');
          for (var benchmarkID, j = 0; benchmarkID = ids[j]; j++) {
            var benchmark = this.benchmarksMap_[benchmarkID];
            if (!benchmark)
              continue;
            benchmark.setEnabled(false, true);
          }
          break;
      }
    }
  }
})();

/**
 * Class representing a single benchmark.
 *
 * @param {robohornet.Runner} runner Test runner instance.
 * @param {Object} details Benchmarks details as json object.
 * @constructor
 */
robohornet.Benchmark = function(runner, details) {
  this.runner = runner;
  if (!details) details = {};
  this.name = details.name;
  this.description = details.description;
  this.filename = details.filename;
  this.runs = details.runs;
  this.weight = details.weight;
  this.baselineTime = details.baselineTime;

  this.id = this.filename.match(/\/([A-z]+)\./)[1].toLowerCase();

  this.loadCallback_ = bind(this.onFrameLoaded_, this);
  this.errorCallback_ = bind(this.onFrameError_, this);
  this.toggleCallback_ = bind(this.enabledClicked_, this);
};

(function() {
  var _p = robohornet.Benchmark.prototype;

  _p.addCell_ = function(rowElement, textContent, opt_className) {
    var cell = document.createElement('td');
    if (opt_className)
      cell.className = opt_className;
    cell.appendChild(document.createTextNode(textContent));
    rowElement.appendChild(cell);
  };

  _p.register = function() {
    var identifier = 'benchmark-' + this.index;

    // Append summary row.
    var row = document.createElement('tr');
    row.id = identifier;
    var cell = document.createElement('td');
    var checkbox = document.createElement('input');
    checkbox.type = 'checkbox';
    checkbox.id = identifier + '-toggle';
    checkbox.checked = true;
    this.toggleElement_ = checkbox;
    this.toggleElement_.addEventListener('click', this.toggleCallback_, false);
    cell.appendChild(checkbox);

    var label = document.createElement('label');
    label.htmlFor = checkbox.id;
    label.appendChild(document.createTextNode(this.name));
    cell.appendChild(label);

    row.appendChild(cell);

    this.addCell_(row, '-');
    this.addCell_(row, '-', 'number');
    this.addCell_(row, this.baselineTime.toFixed(2) + 'ms', 'number');
    this.addCell_(row, this.computedWeight.toFixed(2) + '%', 'number');
    this.addCell_(row, '-', 'number');
    this.runner.testsContainer.tBodies[0].appendChild(row);
    this.rowElement_ = row;

    // Append details row.
    row = document.createElement('tr');
    cell = document.createElement('td');
    cell.className = 'details';
    cell.colSpan = 2;

    var detailsElement = document.createElement('div');
    detailsElement.className = 'details-container';
    cell.appendChild(detailsElement);
    detailsElement.appendChild(document.createTextNode(this.description));

    // Append list of runs/parameters.
    var runsTable = document.createElement('table');
    runsTable.id = identifier + '-runs';
    runsTable.className = 'runs';
    runsTable.appendChild(document.createElement('thead'));

    var headerRow = document.createElement('tr');
    this.addCell_(headerRow, 'Parameters');
    this.addCell_(headerRow, 'Runs', 'number');
    this.addCell_(headerRow, 'Error', 'number');
    this.addCell_(headerRow, 'Mean', 'number');
    runsTable.tHead.appendChild(headerRow);

    runsTable.appendChild(document.createElement('tbody'));
    for (var i = 0; i < this.runs.length; i++) {
      var runsRow = document.createElement('tr');
      this.addCell_(runsRow, this.runs[i][0], 'name');
      this.addCell_(runsRow, '0', 'number');
      this.addCell_(runsRow, '0', 'number');
      this.addCell_(runsRow, '0', 'number');
      runsTable.tBodies[0].appendChild(runsRow);
    }
    detailsElement.appendChild(runsTable);

    this.detailsElement_ = detailsElement;
    this.onToggle_();

    row.appendChild(cell);
    this.runner.testsContainer.tBodies[0].appendChild(row);
  };

  _p.enabledClicked_ = function() {
    this.onToggle_();
    this.runner.updateHash();
  }

  _p.setEnabled = function(enabled, opt_skipUpdateHash) {
    this.toggleElement_.checked = enabled;
    this.onToggle_();
    if (!opt_skipUpdateHash)
      this.runner.updateHash();
  }

  _p.onToggle_ = function() {
    this.enabled = this.toggleElement_.checked;
    this.detailsElement_.className = 'details-container ' + (this.enabled ?
        'enabled' : 'disabled');
  };

  _p.load = function() {
    if (!this.enabled) {
      this.setStatus_('Skipped');
      this.runner.benchmarkSkipped(false);
      return;
    }

    this.runner.testFrame.addEventListener('load', this.loadCallback_, false);
    this.runner.testFrame.addEventListener('error', this.errorCallback_, false);

    this.setStatus_('Loading...');
    this.runner.testFrame.src = this.filename;
  };

  _p.onComplete_ = function(suite) {
    var results = [];
    for (var run, i = 0; run = suite[i]; i++) {
      results.push({
        name: run.name,
        mean: run.stats.mean * 1000,
        rme: run.stats.RME,
        runs: run.stats.size
      });
    }
    this.setResults(results);
    this.runner.benchmarkSucceeded();
  };

  _p.onFrameLoaded_ = function() {
    this.removeListeners_();

    var win = this.runner.testFrame.contentWindow;
    if (!win.test) {
      this.setStatus_('Invalid file.');
      this.runner.benchmarkSkipped(true);
      return;
    }

    var self = this;
    var suite = new Benchmark.Suite(this.name, {
      onComplete: function() { self.onComplete_(this); }
    });

    for (var run, i = 0; run = this.runs[i]; i++) {
      var argument = run[1];
      suite.add(run[0], bind(win.test, win, argument), {
        setup: bind(win.setUp, win, argument),
        teardown: bind(win.tearDown, win, argument)
      });
    }

    this.setStatus_('Running...');
    suite.run(true);
  };

  _p.onFrameError_ = function() {
    this.removeListeners_();
    this.setStatus_('Unable to load file.');
    this.runner.benchmarkSkipped(true);
  };

  _p.removeListeners_ = function() {
    this.runner.testFrame.removeEventListener('load', this.loadCallback_,
        false);
    this.runner.testFrame.removeEventListener('error', this.errorCallback_,
        false);
  };

  _p.setResults = function(results) {
    var row = this.rowElement_;
    row.cells[1].textContent = 'Computing Score...';

    var accumulatedMean = 0;
    var runsTable = document.getElementById(row.id + '-runs');
    for (var result, i = 0; result = results[i]; i++) {
      var runCells = runsTable.tBodies[0].rows[i].cells;
      runCells[1].textContent = result.runs;
      runCells[2].textContent = String.fromCharCode(177) +
          result.rme.toFixed(2) + '%';
      runCells[3].textContent = result.mean.toFixed(2) + 'ms';
      accumulatedMean += result.mean;
    }

    var diff = accumulatedMean - this.baselineTime;
    var score = this.baselineTime * this.computedWeight / accumulatedMean;
    this.runner.incrementOverallScore(score);

    row.cells[1].textContent = 'Completed successfully ';
    row.cells[2].textContent = accumulatedMean.toFixed(2) + 'ms';
    row.cells[5].textContent = score.toFixed(2);
  };

  _p.setStatus_ = function(statusText) {
    var row = this.rowElement_;
    row.cells[1].textContent = statusText;
  };
})();

function bind(fn, opt_scope, var_args) {
  var scope = opt_scope || window;
  var len = arguments.length;
  var args = [];
  for (var i = 2; i < len; i++) {
  args.push(arguments[i]);
  }
  return function() {
  fn.apply(scope, args);
  };
}
<|endoftext|>


<commit_before>// Router for /conf

var express = require('express');
var router = express.Router();

var mongoose = require('mongoose');
var Conf = mongoose.model('Conf');
var Counter = mongoose.model('Counter');
var User = mongoose.model('User');

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

function newConf(title, group, uid, cb) {
  Counter.getNext("conf", function(err, id) {
    if(err) return cb(err, null);

    var conf = new Conf({
      _id: id,
      title,
      group,
      members: [{
        _id: uid,
        role: 1
      }]
    });
    conf.save(function(err, doc) {
      if(err) {
        if(err.code == 11000) {
          // Duplicated key
          return cb(false, null);
        } else return cb(err, null);
      }
      else return cb(false, id);
    });
  });
}

/**
 * Listing
 */

router.get('/', helpers.loggedin, (req, res, next) => {
  Conf.find({$or: [
    { "members._id": req.user._id },
    { "academicMembers._id": req.user._id },
    { "participants._id": req.user._id }
  ]}).select("title").lean().exec((err, docs) => {
    if(err) return next(err);
    else return res.send({ confs: docs });
  });
});

router.get('/available', helpers.loggedin, (req, res, next) => {
  Conf.find({ status: { $gt: 0 } }).select("title").lean().exec((err, docs) => {
    if(err) return next(err);
    else res.send({ confs: docs });
  });
});

/**
 * Creation
 */

router.post('/', helpers.hasFields(['title', 'group']), helpers.groupOwner, (req, res, next) => {
  function cb(err, id) {
    if(err) next(err);
    else if(id) {
      res.send({
        msg: "OperationSuccessful",
        id: id
      });
    } else newConf(req.body.title, req.body.group, req.user._id, cb)
  };
  newConf(req.body.title, req.body.group, req.user._id, cb);
});

/**
 * Data
 */

router.get('/:conf(\\d+)', helpers.loggedin, (req, res, next) => {
  Conf.findById(req.params.conf).select("title members roles status").lean().exec((err, doc) => {
    if(err) return next(err);
    else res.send(doc);
  });
});

/**
 * Member and roles
 */

router.post('/:conf(\\d+)/members/:member(\\d+)',
  helpers.hasPerms(['members.modify']),
  helpers.hasFields(['role']),
  (req, res, next) => {
    User.findById(req.params.member).exec((err, doc) => {
      if(err) next(err);
      else if(doc) {
        Conf.findOneAndUpdate({
          _id: req.params.conf,
          'members._id': req.params.member,
        }, {
          'members.$.role': req.body.role,
        }).exec((err, doc) => {
          if(err) return next(err);
          else if(doc) return res.send({ msg: 'OperationSuccessful' });
          else {
            Conf.findByIdAndUpdate(req.params.conf, { $push: { members: { _id: req.params.member, role: req.body.role }}})
              .exec((err, doc) => {
                if(err) return next(err);
                else return res.send({ msg: 'OperationSuccessful' });
              });
          }
        });
      } else {
        res.sendStatus(400);
      }
    });
  });

router.delete('/:conf(\\d+)/members/:member(\\d+)',
  helpers.hasPerms(['members.modify']),
  (req, res, next) => {
    Conf.findByIdAndUpdate(req.params.conf, { $pull: { members: { $elemMatch: { _id: req.params.member }}}})
      .exec((err, doc) => {
        if(err) return next(err);
        else return res.send({ msg: 'OperationSuccessful' });
      });
  });

/**
 * Forms and applications
 */

router.post('/:conf(\\d+)/academic/form',
  helpers.hasPerms(['form.academic.modify']),
  helpers.hasFields(['form']),
  (req, res, next) => {
    //TODO: lint the input

    Conf.findByIdAndUpdate(req.params.conf, { $set: { academicForm: JSON.stringify(req.body.form) } }).exec((err, doc) => {
      if(err) return next(err);
      else return res.send({
        msg: "OperationSuccessful"
      });
    });
});

router.post('/:conf(\\d+)/participants/form',
  helpers.hasPerms(['form.participant.edit']),
  helpers.hasFields(['form']),
  (req, res, next) => {
    Conf.findByIdAndUpdate(req.params.conf, { $set: { participantForm : JSON.stringify(req.body.form) } }).exec((err, doc) => {
      if(err) return next(err);
      else return res.send({
        msg: "OperationSuccessful"
      });
    });
  });

router.post('/:conf(\\d+)/academic/:member(\\d+)',
  helpers.loggedin,
  helpers.confExists,
  helpers.hasPerms(['form.academic.view.modify'], (req) => req.user && req.params.member == req.user._id ),
  helpers.hasFields(['content']),
  (req, res, next) => {
    Conf.findOneAndUpdate({
      _id: req.params.conf,
      'academicMembers._id': req.params.member,
    }, {
      'academicMembers.$.submission': JSON.stringify(req.body.content)
    }).exec((err, doc) => {
      if(err) return next(err);
      else if(doc) return res.send({ msg: "OperationSuccessful" });
      else {
        Conf.findByIdAndUpdate(req.params.conf, { $push: { academicMembers: { _id: req.params.member, submission: JSON.stringify(req.body.content) }}})
          .exec((err, doc) => {
            if(err) return next(err);
            else return res.send({ msg: "OperationSuccessful" });
          });
      }
    });
  });

router.get('/:conf(\\d+)/academic/:member(\\d+)',
  helpers.hasPerms(['form.academic.view'], (req) => req.user && req.params.member == req.user._id ),
  (req, res, next) => {
    Conf.findById(req.params.conf, { 'academicMembers._id': req.params.member, academicMembers: true }).exec((err, doc) => {
      if(err) return next(err);

      // If the current user is the requested user, then it's possible that the conf doesn't exist
      else if(doc && doc.academicMembers) return res.send(doc.academicMembers[0]);
      else return res.send({ error: "NoSuchMember" });
    });
  });

router.get('/:conf(\\d+)/academic',
  helpers.loggedin,
  helpers.confExists,
  (req, res, next) => {
    Conf.findById(req.params.conf).select('academicMembers._id').exec((err, doc) => {
      if(err) return next(err);
      //TODO: check for conf status
      else return res.send(doc.toObject());
    });
  });

module.exports = router;
<commit_msg>Returning user data when querying conf data<commit_after>// Router for /conf

var express = require('express');
var router = express.Router();

var mongoose = require('mongoose');
var Conf = mongoose.model('Conf');
var Counter = mongoose.model('Counter');
var User = mongoose.model('User');

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

function newConf(title, group, uid, cb) {
  Counter.getNext("conf", function(err, id) {
    if(err) return cb(err, null);

    var conf = new Conf({
      _id: id,
      title,
      group,
      members: [{
        _id: uid,
        role: 1
      }]
    });
    conf.save(function(err, doc) {
      if(err) {
        if(err.code == 11000) {
          // Duplicated key
          return cb(false, null);
        } else return cb(err, null);
      }
      else return cb(false, id);
    });
  });
}

/**
 * Listing
 */

router.get('/', helpers.loggedin, (req, res, next) => {
  Conf.find({$or: [
    { "members._id": req.user._id },
    { "academicMembers._id": req.user._id },
    { "participants._id": req.user._id }
  ]}).select("title").lean().exec((err, docs) => {
    if(err) return next(err);
    else return res.send({ confs: docs });
  });
});

router.get('/available', helpers.loggedin, (req, res, next) => {
  Conf.find({ status: { $gt: 0 } }).select("title").lean().exec((err, docs) => {
    if(err) return next(err);
    else res.send({ confs: docs });
  });
});

/**
 * Creation
 */

router.post('/', helpers.hasFields(['title', 'group']), helpers.groupOwner, (req, res, next) => {
  function cb(err, id) {
    if(err) next(err);
    else if(id) {
      res.send({
        msg: "OperationSuccessful",
        id: id
      });
    } else newConf(req.body.title, req.body.group, req.user._id, cb)
  };
  newConf(req.body.title, req.body.group, req.user._id, cb);
});

/**
 * Data
 */

router.get('/:conf(\\d+)', helpers.loggedin, (req, res, next) => {
  Conf.findById(req.params.conf).select("title members roles status").lean().exec((err, conf) => {
    if(err) return next(err);
    else {
      Promise.all([
        new Promise((resolve, reject) => {
          if(!conf.members) resolve([]);
          else User.find({ _id: { $in: conf.members.map((e) => e._id) }}).select("realname email").lean().exec((err, users) => {
            if(err) reject(err);
            else resolve(users);
          });
        })
      ]).then((result) => {
        console.log(result);
        res.send({
          conf: conf,
          members: result[0]
        });
      }, (reason) => {
        next(err);
      });
    }
  });
});

/**
 * Member and roles
 */

router.post('/:conf(\\d+)/members/:member(\\d+)',
  helpers.hasPerms(['members.modify']),
  helpers.hasFields(['role']),
  (req, res, next) => {
    User.findById(req.params.member).exec((err, doc) => {
      if(err) next(err);
      else if(doc) {
        Conf.findOneAndUpdate({
          _id: req.params.conf,
          'members._id': req.params.member,
        }, {
          'members.$.role': req.body.role,
        }).exec((err, doc) => {
          if(err) return next(err);
          else if(doc) return res.send({ msg: 'OperationSuccessful' });
          else {
            Conf.findByIdAndUpdate(req.params.conf, { $push: { members: { _id: req.params.member, role: req.body.role }}})
              .exec((err, doc) => {
                if(err) return next(err);
                else return res.send({ msg: 'OperationSuccessful' });
              });
          }
        });
      } else {
        res.sendStatus(400);
      }
    });
  });

router.delete('/:conf(\\d+)/members/:member(\\d+)',
  helpers.hasPerms(['members.modify']),
  (req, res, next) => {
    Conf.findByIdAndUpdate(req.params.conf, { $pull: { members: { $elemMatch: { _id: req.params.member }}}})
      .exec((err, doc) => {
        if(err) return next(err);
        else return res.send({ msg: 'OperationSuccessful' });
      });
  });

/**
 * Forms and applications
 */

router.post('/:conf(\\d+)/academic/form',
  helpers.hasPerms(['form.academic.modify']),
  helpers.hasFields(['form']),
  (req, res, next) => {
    //TODO: lint the input

    Conf.findByIdAndUpdate(req.params.conf, { $set: { academicForm: JSON.stringify(req.body.form) } }).exec((err, doc) => {
      if(err) return next(err);
      else return res.send({
        msg: "OperationSuccessful"
      });
    });
});

router.post('/:conf(\\d+)/participants/form',
  helpers.hasPerms(['form.participant.edit']),
  helpers.hasFields(['form']),
  (req, res, next) => {
    Conf.findByIdAndUpdate(req.params.conf, { $set: { participantForm : JSON.stringify(req.body.form) } }).exec((err, doc) => {
      if(err) return next(err);
      else return res.send({
        msg: "OperationSuccessful"
      });
    });
  });

router.post('/:conf(\\d+)/academic/:member(\\d+)',
  helpers.loggedin,
  helpers.confExists,
  helpers.hasPerms(['form.academic.view.modify'], (req) => req.user && req.params.member == req.user._id ),
  helpers.hasFields(['content']),
  (req, res, next) => {
    Conf.findOneAndUpdate({
      _id: req.params.conf,
      'academicMembers._id': req.params.member,
    }, {
      'academicMembers.$.submission': JSON.stringify(req.body.content)
    }).exec((err, doc) => {
      if(err) return next(err);
      else if(doc) return res.send({ msg: "OperationSuccessful" });
      else {
        Conf.findByIdAndUpdate(req.params.conf, { $push: { academicMembers: { _id: req.params.member, submission: JSON.stringify(req.body.content) }}})
          .exec((err, doc) => {
            if(err) return next(err);
            else return res.send({ msg: "OperationSuccessful" });
          });
      }
    });
  });

router.get('/:conf(\\d+)/academic/:member(\\d+)',
  helpers.hasPerms(['form.academic.view'], (req) => req.user && req.params.member == req.user._id ),
  (req, res, next) => {
    Conf.findById(req.params.conf, { 'academicMembers._id': req.params.member, academicMembers: true }).exec((err, doc) => {
      if(err) return next(err);

      // If the current user is the requested user, then it's possible that the conf doesn't exist
      else if(doc && doc.academicMembers) return res.send(doc.academicMembers[0]);
      else return res.send({ error: "NoSuchMember" });
    });
  });

router.get('/:conf(\\d+)/academic',
  helpers.loggedin,
  helpers.confExists,
  (req, res, next) => {
    Conf.findById(req.params.conf).select('academicMembers._id').exec((err, doc) => {
      if(err) return next(err);
      //TODO: check for conf status
      else return res.send(doc.toObject());
    });
  });

module.exports = router;
<|endoftext|>


<commit_before>/**
 * @fileoverview Prevents usage of Function.prototype.bind and arrow functions
 *               in React component definition.
 * @author Daniel Lo Nigro <dan.cx>
 */
'use strict';

// -----------------------------------------------------------------------------
// Requirements
// -----------------------------------------------------------------------------

const rule = require('../../../lib/rules/jsx-no-bind');
const RuleTester = require('eslint').RuleTester;

const parserOptions = {
  ecmaVersion: 8,
  sourceType: 'module',
  ecmaFeatures: {
    experimentalObjectRestSpread: true,
    jsx: true
  }
};

// -----------------------------------------------------------------------------
// Tests
// -----------------------------------------------------------------------------

const ruleTester = new RuleTester({parserOptions});
ruleTester.run('jsx-no-bind', rule, {

  valid: [
    // Not covered by the rule
    {
      code: '

',
      parser: 'babel-eslint'
    },
    {
      code: '

',
      parser: 'babel-eslint'
    },
    {
      code: '

',
      parser: 'babel-eslint'
    },

    // bind() and arrow functions in refs explicitly ignored
    {
      code: '
 this._input = c}>
',
      options: [{ignoreRefs: true}],
      parser: 'babel-eslint'
    },
    {
      code: '

',
      options: [{ignoreRefs: true}],
      parser: 'babel-eslint'
    },

    // bind() explicitly allowed
    {
      code: '

',
      options: [{allowBind: true}],
      parser: 'babel-eslint'
    },

    // Arrow functions explicitly allowed
    {
      code: '
 alert("1337")}>
',
      options: [{allowArrowFunctions: true}],
      parser: 'babel-eslint'
    },

    // Redux connect
    {
      code: `
        class Hello extends Component {
          render() {
            return
Hello
;
          }
        }
        export default connect()(Hello);
      `,
      options: [{allowBind: true}],
      parser: 'babel-eslint'
    },

    // Backbone view with a bind
    {
      code: `
        var DocumentRow = Backbone.View.extend({
          tagName: "li",
          render: function() {
            this.onTap.bind(this);
          }
        });
      `,
      parser: 'babel-eslint'
    },
    {
      code: `
        const foo = {
          render: function() {
            this.onTap.bind(this);
            return true;
          }
        };
      `,
      parser: 'babel-eslint'
    },
    {
      code: `
        const foo = {
          render() {
            this.onTap.bind(this);
            return true;
          }
        };
      `,
      parser: 'babel-eslint'
    },

    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    const click = this.onTap.bind(this);',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    foo.onClick = this.onTap.bind(this);',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    return (
{',
        '      this.props.list.map(this.wrap.bind(this, "span"))',
        '    }
);',
        '  }',
        '};'
      ].join('\n'),
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    const click = () => true;',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    return (
{',
        '      this.props.list.map(item => <item hello="true"/>)',
        '    }
);',
        '  }',
        '};'
      ].join('\n'),
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    const click = this.bar::baz',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    return (
{',
        '      this.props.list.map(this.bar::baz)',
        '    }
);',
        '  }',
        '};'
      ].join('\n'),
      parser: 'babel-eslint'
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '    return (
{',
        '      this.props.list.map(this.wrap.bind(this, "span"))',
        '    }
);',
        '  }',
        '});'
      ].join('\n'),
      parser: 'babel-eslint'
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '    const click = this.bar::baz',
        '    return
Hello
;',
        '  }',
        '});'
      ].join('\n'),
      parser: 'babel-eslint'
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '    const click = () => true',
        '    return
Hello
;',
        '  }',
        '});'
      ].join('\n'),
      parser: 'babel-eslint'
    }
  ],

  invalid: [
    // .bind()
    {
      code: '

',
      errors: [{message: 'JSX props should not use .bind()'}],
      parser: 'babel-eslint'
    },
    {
      code: '

',
      errors: [{message: 'JSX props should not use .bind()'}],
      parser: 'babel-eslint'
    },
    {
      code: '

',
      errors: [{message: 'JSX props should not use .bind()'}],
      parser: 'babel-eslint'
    },
    {
      code: '

',
      errors: [{message: 'JSX props should not use .bind()'}],
      parser: 'babel-eslint'
    },
    {
      code: `
        var Hello = createReactClass({
          render: function() {
            const click = this.someMethod.bind(this);
            return
Hello {this.state.name}
;
          }
        });
      `,
      errors: [{message: 'JSX props should not use .bind()'}],
      parser: 'babel-eslint'
    },
    {
      code: `
        class Hello23 extends React.Component {
          render() {
            const click = this.someMethod.bind(this);
            return
Hello {this.state.name}
;
          }
        };
      `,
      errors: [{message: 'JSX props should not use .bind()'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv() {',
        '    const click = this.doSomething.bind(this, "no")',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [{message: 'JSX props should not use .bind()'}],
      parser: 'babel-eslint'
    },
    {
      code: `
        const foo = {
          render: ({onClick}) => (

Hello

          )
        };
      `,
      errors: [{message: 'JSX props should not use .bind()'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '   return
',
        '  }',
        '});'
      ].join('\n'),
      errors: [{message: 'JSX props should not use .bind()'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '    const doThing = this.doSomething.bind(this, "hey")',
        '    return
',
        '  }',
        '});'
      ].join('\n'),
      errors: [{message: 'JSX props should not use .bind()'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv = () => {',
        '    const click = () => true',
        '    const renderStuff = () => {',
        '      const click = this.doSomething.bind(this, "hey")',
        '      return
',
        '    }',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [
        {message: 'JSX props should not use .bind()'},
        {message: 'JSX props should not use arrow functions'}
      ],
      parser: 'babel-eslint'
    },

    // Arrow functions
    {
      code: '
 alert("1337")}>
',
      errors: [{message: 'JSX props should not use arrow functions'}],
      parser: 'babel-eslint'
    },
    {
      code: '
 42}>
',
      errors: [{message: 'JSX props should not use arrow functions'}],
      parser: 'babel-eslint'
    },
    {
      code: '
 { first(); second(); }}>
',
      errors: [{message: 'JSX props should not use arrow functions'}],
      parser: 'babel-eslint'
    },
    {
      code: '
 this._input = c}>
',
      errors: [{message: 'JSX props should not use arrow functions'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv = () => {',
        '    const click = () => true',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [{message: 'JSX props should not use arrow functions'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '   return
 true} />',
        '  }',
        '});'
      ].join('\n'),
      errors: [{message: 'JSX props should not use arrow functions'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '    const doThing = () => true',
        '    return
',
        '  }',
        '});'
      ].join('\n'),
      errors: [{message: 'JSX props should not use arrow functions'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv = () => {',
        '    const click = ::this.onChange',
        '    const renderStuff = () => {',
        '      const click = () => true',
        '      return
',
        '    }',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [
        {message: 'JSX props should not use arrow functions'},
        {message: 'JSX props should not use ::'}
      ],
      parser: 'babel-eslint'
    },

    // Bind expression
    {
      code: '
',
      errors: [{message: 'JSX props should not use ::'}],
      parser: 'babel-eslint'
    },
    {
      code: '
',
      errors: [{message: 'JSX props should not use ::'}],
      parser: 'babel-eslint'
    },
    {
      code: '
',
      errors: [{message: 'JSX props should not use ::'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv() {',
        '    const click = ::this.onChange',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [{message: 'JSX props should not use ::'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv() {',
        '    const click = this.bar::baz',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [{message: 'JSX props should not use ::'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv = () => {',
        '    const click = true',
        '    const renderStuff = () => {',
        '      const click = this.bar::baz',
        '      return
',
        '    }',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [{message: 'JSX props should not use ::'}],
      parser: 'babel-eslint'
    }
  ]
});
<commit_msg>Only use babel parser when necessary on tests<commit_after>/**
 * @fileoverview Prevents usage of Function.prototype.bind and arrow functions
 *               in React component definition.
 * @author Daniel Lo Nigro <dan.cx>
 */
'use strict';

// -----------------------------------------------------------------------------
// Requirements
// -----------------------------------------------------------------------------

const rule = require('../../../lib/rules/jsx-no-bind');
const RuleTester = require('eslint').RuleTester;

const parserOptions = {
  ecmaVersion: 8,
  sourceType: 'module',
  ecmaFeatures: {
    experimentalObjectRestSpread: true,
    jsx: true
  }
};

// -----------------------------------------------------------------------------
// Tests
// -----------------------------------------------------------------------------

const ruleTester = new RuleTester({parserOptions});
ruleTester.run('jsx-no-bind', rule, {

  valid: [
    // Not covered by the rule
    {
      code: '

'
    },
    {
      code: '

'
    },
    {
      code: '

'
    },

    // bind() and arrow functions in refs explicitly ignored
    {
      code: '
 this._input = c}>
',
      options: [{ignoreRefs: true}]
    },
    {
      code: '

',
      options: [{ignoreRefs: true}]
    },

    // bind() explicitly allowed
    {
      code: '

',
      options: [{allowBind: true}]
    },

    // Arrow functions explicitly allowed
    {
      code: '
 alert("1337")}>
',
      options: [{allowArrowFunctions: true}]
    },

    // Redux connect
    {
      code: `
        class Hello extends Component {
          render() {
            return
Hello
;
          }
        }
        export default connect()(Hello);
      `,
      options: [{allowBind: true}]
    },

    // Backbone view with a bind
    {
      code: `
        var DocumentRow = Backbone.View.extend({
          tagName: "li",
          render: function() {
            this.onTap.bind(this);
          }
        });
      `
    },
    {
      code: `
        const foo = {
          render: function() {
            this.onTap.bind(this);
            return true;
          }
        };
      `
    },
    {
      code: `
        const foo = {
          render() {
            this.onTap.bind(this);
            return true;
          }
        };
      `
    },

    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    const click = this.onTap.bind(this);',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n')
    },
    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    foo.onClick = this.onTap.bind(this);',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n')
    },
    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    return (
{',
        '      this.props.list.map(this.wrap.bind(this, "span"))',
        '    }
);',
        '  }',
        '};'
      ].join('\n')
    },
    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    const click = () => true;',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n')
    },
    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    return (
{',
        '      this.props.list.map(item => <item hello="true"/>)',
        '    }
);',
        '  }',
        '};'
      ].join('\n')
    },
    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    const click = this.bar::baz',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello extends Component {',
        '  render() {',
        '    return (
{',
        '      this.props.list.map(this.bar::baz)',
        '    }
);',
        '  }',
        '};'
      ].join('\n'),
      parser: 'babel-eslint'
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '    return (
{',
        '      this.props.list.map(this.wrap.bind(this, "span"))',
        '    }
);',
        '  }',
        '});'
      ].join('\n')
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '    const click = this.bar::baz',
        '    return
Hello
;',
        '  }',
        '});'
      ].join('\n'),
      parser: 'babel-eslint'
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '    const click = () => true',
        '    return
Hello
;',
        '  }',
        '});'
      ].join('\n')
    }
  ],

  invalid: [
    // .bind()
    {
      code: '

',
      errors: [{message: 'JSX props should not use .bind()'}]
    },
    {
      code: '

',
      errors: [{message: 'JSX props should not use .bind()'}]
    },
    {
      code: '

',
      errors: [{message: 'JSX props should not use .bind()'}]
    },
    {
      code: '

',
      errors: [{message: 'JSX props should not use .bind()'}]
    },
    {
      code: `
        var Hello = createReactClass({
          render: function() {
            const click = this.someMethod.bind(this);
            return
Hello {this.state.name}
;
          }
        });
      `,
      errors: [{message: 'JSX props should not use .bind()'}]
    },
    {
      code: `
        class Hello23 extends React.Component {
          render() {
            const click = this.someMethod.bind(this);
            return
Hello {this.state.name}
;
          }
        };
      `,
      errors: [{message: 'JSX props should not use .bind()'}]
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv() {',
        '    const click = this.doSomething.bind(this, "no")',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [{message: 'JSX props should not use .bind()'}]
    },
    {
      code: `
        const foo = {
          render: ({onClick}) => (

Hello

          )
        };
      `,
      errors: [{message: 'JSX props should not use .bind()'}]
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '   return
',
        '  }',
        '});'
      ].join('\n'),
      errors: [{message: 'JSX props should not use .bind()'}]
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '    const doThing = this.doSomething.bind(this, "hey")',
        '    return
',
        '  }',
        '});'
      ].join('\n'),
      errors: [{message: 'JSX props should not use .bind()'}]
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv = () => {',
        '    const click = () => true',
        '    const renderStuff = () => {',
        '      const click = this.doSomething.bind(this, "hey")',
        '      return
',
        '    }',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [
        {message: 'JSX props should not use .bind()'},
        {message: 'JSX props should not use arrow functions'}
      ],
      parser: 'babel-eslint'
    },

    // Arrow functions
    {
      code: '
 alert("1337")}>
',
      errors: [{message: 'JSX props should not use arrow functions'}]
    },
    {
      code: '
 42}>
',
      errors: [{message: 'JSX props should not use arrow functions'}]
    },
    {
      code: '
 { first(); second(); }}>
',
      errors: [{message: 'JSX props should not use arrow functions'}]
    },
    {
      code: '
 this._input = c}>
',
      errors: [{message: 'JSX props should not use arrow functions'}]
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv = () => {',
        '    const click = () => true',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [{message: 'JSX props should not use arrow functions'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '   return
 true} />',
        '  }',
        '});'
      ].join('\n'),
      errors: [{message: 'JSX props should not use arrow functions'}]
    },
    {
      code: [
        'var Hello = React.createClass({',
        '  render: function() { ',
        '    const doThing = () => true',
        '    return
',
        '  }',
        '});'
      ].join('\n'),
      errors: [{message: 'JSX props should not use arrow functions'}]
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv = () => {',
        '    const click = ::this.onChange',
        '    const renderStuff = () => {',
        '      const click = () => true',
        '      return
',
        '    }',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [
        {message: 'JSX props should not use arrow functions'},
        {message: 'JSX props should not use ::'}
      ],
      parser: 'babel-eslint'
    },

    // Bind expression
    {
      code: '
',
      errors: [{message: 'JSX props should not use ::'}],
      parser: 'babel-eslint'
    },
    {
      code: '
',
      errors: [{message: 'JSX props should not use ::'}],
      parser: 'babel-eslint'
    },
    {
      code: '
',
      errors: [{message: 'JSX props should not use ::'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv() {',
        '    const click = ::this.onChange',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [{message: 'JSX props should not use ::'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv() {',
        '    const click = this.bar::baz',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [{message: 'JSX props should not use ::'}],
      parser: 'babel-eslint'
    },
    {
      code: [
        'class Hello23 extends React.Component {',
        '  renderDiv = () => {',
        '    const click = true',
        '    const renderStuff = () => {',
        '      const click = this.bar::baz',
        '      return
',
        '    }',
        '    return
Hello
;',
        '  }',
        '};'
      ].join('\n'),
      errors: [{message: 'JSX props should not use ::'}],
      parser: 'babel-eslint'
    }
  ]
});
<|endoftext|>


<commit_before>$(document).foundation()
<commit_msg>Delete app.js<commit_after><|endoftext|>


<commit_before>var service = null;
var privateGadgetNames = null;
var nameOfGadgetBeingEdited = '';
var entryOfGadgetBeingEdited = null;
var privateGadgetSpecFeedUrl = null;

var SERVICE_NAME = 'esp';
var APP_NAME = 'private-gadget-editor';

var SPINNER = '';
var DEFAULT_SPINNER_ID = 'spinner';

function $(id) {
  return document.getElementById(id);
};

function startSpinner(id) {
  $(id ? id : DEFAULT_SPINNER_ID).innerHTML = SPINNER;
};

function stopSpinner(id) {
  $(id ? id : DEFAULT_SPINNER_ID).innerHTML = '';
};

function initEditor() {
  if (privateGadgetSpecFeedUrl) {
    initGadgetNameList();
  }
};

function noCache(url) {
  return url + '?nocache=' + (new Date().getTime());
};

function setNameOfGadgetBeingEdited(name) {
  nameOfGadgetBeingEdited = name;
  if (name) {
    $('spec-url-wrapper').style.display = 'inline';
    var specUrl = 'http://www.google.com/a/feeds/server/g/domain/' +
        detectDomainName() + '/PrivateGadgetSpec/' + name;
    $('spec-url').href = specUrl;
  } else {
    $('spec-url-wrapper').style.display = 'none';
  }
};

function initGadgetNameList() {
  service = new google.gdata.client.FeedServerService(SERVICE_NAME, APP_NAME);
  service.setGadgetsAuthentication('SIGNED');
  service.getFeed(noCache(privateGadgetSpecFeedUrl), function(response) {
    stopSpinner();
    var entries = response && response.feed.entry ? response.feed.entry : [];
    showPrivateGadgetNames(setPrivateGadgetNames(entries));
  }, function(response) {
    stopSpinner()
    showMessage('Error: failed to load private gadget specs');
  });
  startSpinner();
};

function setPrivateGadgetNames(entries) {
  privateGadgetNames = [];
  for (var i = 0; i < entries.length; i++) {
    var name = entries[i].id.$t;
    name = name.substring(name.lastIndexOf('/') + 1);
    privateGadgetNames.push(name);
  }
  return privateGadgetNames;
};

function showPrivateGadgetNames() {
  var html = ['<select id="gadget-select" onchange="editSelectedGadget()">'];
  html.push('<option value="">Select to open</option>');
  for (var i = 0; i < privateGadgetNames.length; i++) {
    var privateGadgetName = privateGadgetNames[i];
    html.push('<option ', privateGadgetName == nameOfGadgetBeingEdited ? 'selected' : '',
        '>', privateGadgetName, '</option>');
  }
  document.getElementById('gadget-list').innerHTML = html.join('');
};

function getSelectedGadgetName() {
  return document.getElementById('gadget-select').value;
};

function editSelectedGadget() {
  var name = getSelectedGadgetName();
  if (name) {
    service.getEntry(noCache(privateGadgetSpecFeedUrl + '/' + name), function(response) {
      stopSpinner();
      setNameOfGadgetBeingEdited(name);
      entryOfGadgetBeingEdited = response.entry;
      editor.setCode(response.entry.content.entity.specContent);
      editor.editor.syntaxHighlight('init');
    }, function(response) {
      stopSpinner();
      showMessage('Error: failed to open gadget spec "' + name + '"');
    });
    startSpinner();
  } else {
    newGadget();
  }
};

function deleteSelectedGadget() {
  var name = getSelectedGadgetName();
  if (name) {
    service.deleteEntry(privateGadgetSpecFeedUrl + '/' + name, function(response) {
      stopSpinner();
      initEditor();
      newGadget();
    }, function(response) {
      stopSpinner();
      showMessage('Error: failed to delete gadget spec "' + name + '"');
    });
    startSpinner();
  } else {
    alert('Please select a gadget to delete.');
  }
};

function newGadget() {
  setNameOfGadgetBeingEdited('');
  editor.setCode(getGadgetSpecTemplate());
  editor.editor.syntaxHighlight('init');
  showPrivateGadgetNames();
  entryOfGadgetBeingEdited = {xmlns: 'http://www.w3.org/2005/Atom', content: {
      type: 'application/xml', entity: {name: '', specContent: ''}}};
};

function saveGadget(changeName) {
  entryOfGadgetBeingEdited.content.entity.specContent = editor.getCode();
  if (nameOfGadgetBeingEdited && !changeName) {
    service.updateEntry(privateGadgetSpecFeedUrl + '/' + nameOfGadgetBeingEdited,
        entryOfGadgetBeingEdited, function(response) {
      stopSpinner();
    }, function(error) {
      stopSpinner();
      showMessage('Error: failed to update gadget spec "' + nameOfGadgetBeingEdited + '"' + error);
    });
    startSpinner();
  } else {
    var name = changeName ?
      prompt('Please enter new name of gadget (e.g. hello.xml)') :
      prompt('Please enter name of new gadget (e.g. hello.xml)');
    if (!name) {
      return;
    }
    setNameOfGadgetBeingEdited(name);
    if (nameOfGadgetBeingEdited) {
      delete entryOfGadgetBeingEdited.content.entity.id;
      entryOfGadgetBeingEdited.content.entity.name = nameOfGadgetBeingEdited;
      service.insertEntry(privateGadgetSpecFeedUrl,
          entryOfGadgetBeingEdited, function(response) {
        stopSpinner();
        privateGadgetNames.push(nameOfGadgetBeingEdited);
        showPrivateGadgetNames();
      }, function(error) {
        stopSpinner();
        showMessage('Error: failed to add gadget spec "' + nameOfGadgetBeingEdited + '": ' + error);
      });
      startSpinner();
    }
  }
};

function openGadgetByUrl() {
  var gadgetSpecUrl = prompt('Please enter public URL of gadget spec');
  if (gadgetSpecUrl) {
    var params = {};
    params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
    gadgets.io.makeRequest(gadgetSpecUrl, function(response) {
      if (response.rc > 299) {
        showMessage('Error: ' + response.errors);
      } else {
        setNameOfGadgetBeingEdited(null);
        entryOfGadgetBeingEdited = {xmlns: 'http://www.w3.org/2005/Atom', content: {
          type: 'application/xml', entity: {name: '', specContent: response.text}}};
        editor.setCode(response.text);
        editor.editor.syntaxHighlight('init');
      }
    }, params);
  }
};

function getGadgetSpecTemplate() {
  var textArea = document.getElementById('gadget-spec-template');
  return textArea.value || textArea.defaultValue;
};

function showMessage(message) {
  var miniMessage = new gadgets.MiniMessage(null, document.getElementById('message-box'));
  miniMessage.createDismissibleMessage(message);
};

//// google.load('gdata', '1.x', {packages: ['core']});
// google.load('gdata', '1.x', {packages: ['core'], 'other_params': 'debug=1'});
// google.setOnLoadCallback(initEditor);

function initCodePress() {
  editor.style.height = '400px';
  CodePressWrapper.init();

  if (location.href.indexOf('codePressReloaded') < 0) {
    setTimeout(function() {
      if (!$('codepress-iframe').editor) {
        location.href += '&codePressReloaded';
        location.reload();
      }
    }, 500);
  }
};

function detectDomainName() {
  var params = location.href.split('&');
  for (var i = 0; i < params.length; i++) {
    if (params[i].indexOf('parent=') == 0) {
      var p = params[i].split('=');
      var parent = decodeURIComponent(p[1]);
      var r = /google.com(:[0-9]+)?\/a\/([^\/]*)\//.exec(parent);
      var domainName = r ? r[2] : null;
      return domainName;
    }
  }

  return null;
};

function initGadget() {
  var domainName = detectDomainName();
  if (domainName) {
    privateGadgetSpecFeedUrl = 'http://feedserver-enterprise.googleusercontent.com/a/' +
        domainName + '/g/PrivateGadgetSpec';
  } else {
    showMessage('Error: domain name missing');
  }

  gadgets.window.adjustHeight();
};

function init() {
  initCodePress();
  initGadget();
  initEditor();
};

gadgets.util.registerOnLoadHandler(init);
<commit_msg>switched private gadget spec url pattern to new pattern<commit_after>var service = null;
var privateGadgetNames = null;
var nameOfGadgetBeingEdited = '';
var entryOfGadgetBeingEdited = null;
var privateGadgetSpecFeedUrl = null;

var SERVICE_NAME = 'esp';
var APP_NAME = 'private-gadget-editor';

var SPINNER = '';
var DEFAULT_SPINNER_ID = 'spinner';

function $(id) {
  return document.getElementById(id);
};

function startSpinner(id) {
  $(id ? id : DEFAULT_SPINNER_ID).innerHTML = SPINNER;
};

function stopSpinner(id) {
  $(id ? id : DEFAULT_SPINNER_ID).innerHTML = '';
};

function initEditor() {
  if (privateGadgetSpecFeedUrl) {
    initGadgetNameList();
  }
};

function noCache(url) {
  return url + '?nocache=' + (new Date().getTime());
};

function setNameOfGadgetBeingEdited(name) {
  nameOfGadgetBeingEdited = name;
  if (name) {
    $('spec-url-wrapper').style.display = 'inline';
    var specUrl = 'http://feedserver-enterprise.googleusercontent.com/a/' +
        detectDomainName() + '/g/PrivateGadgetSpec/' + name;
    $('spec-url').href = specUrl;
  } else {
    $('spec-url-wrapper').style.display = 'none';
  }
};

function initGadgetNameList() {
  service = new google.gdata.client.FeedServerService(SERVICE_NAME, APP_NAME);
  service.setGadgetsAuthentication('SIGNED');
  service.getFeed(noCache(privateGadgetSpecFeedUrl), function(response) {
    stopSpinner();
    var entries = response && response.feed.entry ? response.feed.entry : [];
    showPrivateGadgetNames(setPrivateGadgetNames(entries));
  }, function(response) {
    stopSpinner()
    showMessage('Error: failed to load private gadget specs');
  });
  startSpinner();
};

function setPrivateGadgetNames(entries) {
  privateGadgetNames = [];
  for (var i = 0; i < entries.length; i++) {
    var name = entries[i].id.$t;
    name = name.substring(name.lastIndexOf('/') + 1);
    privateGadgetNames.push(name);
  }
  return privateGadgetNames;
};

function showPrivateGadgetNames() {
  var html = ['<select id="gadget-select" onchange="editSelectedGadget()">'];
  html.push('<option value="">Select to open</option>');
  for (var i = 0; i < privateGadgetNames.length; i++) {
    var privateGadgetName = privateGadgetNames[i];
    html.push('<option ', privateGadgetName == nameOfGadgetBeingEdited ? 'selected' : '',
        '>', privateGadgetName, '</option>');
  }
  document.getElementById('gadget-list').innerHTML = html.join('');
};

function getSelectedGadgetName() {
  return document.getElementById('gadget-select').value;
};

function editSelectedGadget() {
  var name = getSelectedGadgetName();
  if (name) {
    service.getEntry(noCache(privateGadgetSpecFeedUrl + '/' + name), function(response) {
      stopSpinner();
      setNameOfGadgetBeingEdited(name);
      entryOfGadgetBeingEdited = response.entry;
      editor.setCode(response.entry.content.entity.specContent);
      editor.editor.syntaxHighlight('init');
    }, function(response) {
      stopSpinner();
      showMessage('Error: failed to open gadget spec "' + name + '"');
    });
    startSpinner();
  } else {
    newGadget();
  }
};

function deleteSelectedGadget() {
  var name = getSelectedGadgetName();
  if (name) {
    service.deleteEntry(privateGadgetSpecFeedUrl + '/' + name, function(response) {
      stopSpinner();
      initEditor();
      newGadget();
    }, function(response) {
      stopSpinner();
      showMessage('Error: failed to delete gadget spec "' + name + '"');
    });
    startSpinner();
  } else {
    alert('Please select a gadget to delete.');
  }
};

function newGadget() {
  setNameOfGadgetBeingEdited('');
  editor.setCode(getGadgetSpecTemplate());
  editor.editor.syntaxHighlight('init');
  showPrivateGadgetNames();
  entryOfGadgetBeingEdited = {xmlns: 'http://www.w3.org/2005/Atom', content: {
      type: 'application/xml', entity: {name: '', specContent: ''}}};
};

function saveGadget(changeName) {
  entryOfGadgetBeingEdited.content.entity.specContent = editor.getCode();
  if (nameOfGadgetBeingEdited && !changeName) {
    service.updateEntry(privateGadgetSpecFeedUrl + '/' + nameOfGadgetBeingEdited,
        entryOfGadgetBeingEdited, function(response) {
      stopSpinner();
    }, function(error) {
      stopSpinner();
      showMessage('Error: failed to update gadget spec "' + nameOfGadgetBeingEdited + '"' + error);
    });
    startSpinner();
  } else {
    var name = changeName ?
      prompt('Please enter new name of gadget (e.g. hello.xml)') :
      prompt('Please enter name of new gadget (e.g. hello.xml)');
    if (!name) {
      return;
    }
    setNameOfGadgetBeingEdited(name);
    if (nameOfGadgetBeingEdited) {
      delete entryOfGadgetBeingEdited.content.entity.id;
      entryOfGadgetBeingEdited.content.entity.name = nameOfGadgetBeingEdited;
      service.insertEntry(privateGadgetSpecFeedUrl,
          entryOfGadgetBeingEdited, function(response) {
        stopSpinner();
        privateGadgetNames.push(nameOfGadgetBeingEdited);
        showPrivateGadgetNames();
      }, function(error) {
        stopSpinner();
        showMessage('Error: failed to add gadget spec "' + nameOfGadgetBeingEdited + '": ' + error);
      });
      startSpinner();
    }
  }
};

function openGadgetByUrl() {
  var gadgetSpecUrl = prompt('Please enter public URL of gadget spec');
  if (gadgetSpecUrl) {
    var params = {};
    params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
    gadgets.io.makeRequest(gadgetSpecUrl, function(response) {
      if (response.rc > 299) {
        showMessage('Error: ' + response.errors);
      } else {
        setNameOfGadgetBeingEdited(null);
        entryOfGadgetBeingEdited = {xmlns: 'http://www.w3.org/2005/Atom', content: {
          type: 'application/xml', entity: {name: '', specContent: response.text}}};
        editor.setCode(response.text);
        editor.editor.syntaxHighlight('init');
      }
    }, params);
  }
};

function getGadgetSpecTemplate() {
  var textArea = document.getElementById('gadget-spec-template');
  return textArea.value || textArea.defaultValue;
};

function showMessage(message) {
  var miniMessage = new gadgets.MiniMessage(null, document.getElementById('message-box'));
  miniMessage.createDismissibleMessage(message);
};

//// google.load('gdata', '1.x', {packages: ['core']});
// google.load('gdata', '1.x', {packages: ['core'], 'other_params': 'debug=1'});
// google.setOnLoadCallback(initEditor);

function initCodePress() {
  editor.style.height = '400px';
  CodePressWrapper.init();

  if (location.href.indexOf('codePressReloaded') < 0) {
    setTimeout(function() {
      if (!$('codepress-iframe').editor) {
        location.href += '&codePressReloaded';
        location.reload();
      }
    }, 500);
  }
};

function detectDomainName() {
  var params = location.href.split('&');
  for (var i = 0; i < params.length; i++) {
    if (params[i].indexOf('parent=') == 0) {
      var p = params[i].split('=');
      var parent = decodeURIComponent(p[1]);
      var r = /google.com(:[0-9]+)?\/a\/([^\/]*)\//.exec(parent);
      var domainName = r ? r[2] : null;
      return domainName;
    }
  }

  return null;
};

function initGadget() {
  var domainName = detectDomainName();
  if (domainName) {
    privateGadgetSpecFeedUrl = 'http://feedserver-enterprise.googleusercontent.com/a/' +
        domainName + '/g/PrivateGadgetSpec';
  } else {
    showMessage('Error: domain name missing');
  }

  gadgets.window.adjustHeight();
};

function init() {
  initCodePress();
  initGadget();
  initEditor();
};

gadgets.util.registerOnLoadHandler(init);
<|endoftext|>


<commit_before>describe('Controller: AllDocuments Controller', function() {
  // new instance of the module
  beforeEach(angular.mock.module('frodocms'));

  var controller, Document, $window;
  // instantiate the main controller
  beforeEach(function() {
    $window = {
      location: {
        reload: sinon.stub()
      }
    };
    angular.mock.module(function($provide) {
      $provide.value('$window', $window);
    });
    angular.mock.inject(function($injector, $controller) {
      Document = $injector.get('Document');
      Document.all = sinon.spy();
      controller = $controller('AllDocumentsController');
    });
  });

  describe('Initialization', function() {
    it('should verify that Document.all function is defined and is called',
      function() {
        expect(Document.all.called).toBe(true);
        expect(typeof Document.all).toBe('function');
        var data = {
            data: 'data'
          },
          err = 'err';
        Document.all.args[0][0](err, data);
        expect(controller.documents).toBeDefined();
        expect(controller.documents.data).toBe('data');
      });

    it('should verify that Document.delete function is defined and is called',
      function() {
        Document.delete = sinon.spy();
        controller.delete('id');
        expect(Document.delete.called).toBe(true);
        expect(typeof Document.delete).toBe('function');
        expect(controller.processing).toBe(true);
        var data = {
          message: {
            _id: true
          }
        };
        controller.documents = {
          filter: function() {
            return 'filter';
          }
        };
        Document.delete.args[0][1](data);
        expect(controller.processing).toBe(false);
        Document.delete.args[0][1]({
          message: 'message'
        });
        expect(controller.error).toBeDefined();
        expect(controller.error).toBe('message');
      });

    it('should verify that Document.update function is defined and is called',
      function() {
        Document.update = sinon.spy();
        controller.docData = {
          title: 'title',
          content: 'content'
        };
        controller.update('id');
        expect(Document.update.called).toBe(true);
        expect(typeof Document.delete).toBe('function');
        expect(controller.processing).toBe(true);
        expect(controller.docData).toBeDefined();
        Document.all = sinon.spy();
        Document.update.args[0][2]({
          success: true
        });
        expect(Document.all.called).toBe(true);
        Document.all.args[0][0]('err','data');
        expect(controller.documents).toEqual('data');
        Document.update.args[0][2]({
          success: false,
          message: 'message'
        });
        expect(controller.error).toBeDefined();
        expect(controller.error).toEqual('message');
      });
  });
});
<commit_msg>[#112790335] Updates tests for document update controller<commit_after>describe('Controller: AllDocuments Controller', function() {
  // new instance of the module
  beforeEach(angular.mock.module('frodocms'));

  var controller, Document, $window;
  // instantiate the main controller
  beforeEach(function() {
    $window = {
      location: {
        reload: sinon.stub()
      }
    };
    angular.mock.module(function($provide) {
      $provide.value('$window', $window);
    });
    angular.mock.inject(function($injector, $controller) {
      Document = $injector.get('Document');
      Document.all = sinon.spy();
      controller = $controller('AllDocumentsController');
    });
  });

  describe('Initialization', function() {
    it('should verify that Document.all function is defined and is called',
      function() {
        expect(Document.all.called).toBe(true);
        expect(typeof Document.all).toBe('function');
        var data = {
            data: 'data'
          },
          err = 'err';
        Document.all.args[0][0](err, data);
        expect(controller.documents).toBeDefined();
        expect(controller.documents.data).toBe('data');
      });

    it('should verify that Document.delete function is defined and is called',
      function() {
        Document.delete = sinon.spy();
        controller.delete('id');
        expect(Document.delete.called).toBe(true);
        expect(typeof Document.delete).toBe('function');
        expect(controller.processing).toBe(true);
        var data = {
          message: {
            _id: true
          }
        };
        controller.documents = {
          filter: function() {
            return 'filter';
          }
        };
        Document.delete.args[0][1](data);
        expect(controller.processing).toBe(false);
        Document.delete.args[0][1]({
          message: 'message'
        });
        expect(controller.error).toBeDefined();
        expect(controller.error).toBe('message');
      });

    it('should verify that Document.update function is defined and is called',
      function() {
        Document.update = sinon.spy();
        controller.docData = {
          title: 'title',
          content: 'content'
        };
        controller.update('id');
        expect(Document.update.called).toBe(true);
        expect(typeof Document.delete).toBe('function');
        expect(controller.processing).toBe(true);
        expect(controller.docData).toBeDefined();

        Document.all = sinon.spy();
        Document.update.args[0][2]({
          success: true
        });
        expect(Document.all.called).toBe(true);

        Document.all.args[0][0]('err','data');
        expect(controller.documents).toEqual('data');
        Document.update.args[0][2]({
          success: false,
          message: 'message'
        });
        expect(controller.error).toBeDefined();
        expect(controller.error).toEqual('message');
      });
  });
});
<|endoftext|>


<commit_before>// ==UserScript==
// @name         PlanMill Login Redirect
// @description  Redirects an expired session to a login page that doesn't fail.
// @version      1.1.0
// @homepage     https://bitbucket.org/scoobadog/tampermonkey/
// @updateURL    https://bitbucket.org/scoobadog/tampermonkey/raw/master/planmill-login-redirect.js
// @include      /^https://online\.planmill\.com/.+/.+$/
// @grant        none
// @run-at       document-body
// ==/UserScript==
if (document.getElementById("logindiv") !== null) {
	var path = window.location.pathname;
	var url = window.location.href
		.replace(path, path.substr(0, path.indexOf("/", 1)))
		.replace(window.location.search, "") + "/";

	if (url.length < window.location.href.length) {
		window.location.replace(url)
	}
}
<commit_msg>Added a redirect from security check page back to login page<commit_after>// ==UserScript==
// @name         PlanMill Login Redirect
// @description  Redirects an expired session to a login page that doesn't fail.
// @version      1.2.0
// @homepage     https://bitbucket.org/scoobadog/tampermonkey/
// @updateURL    https://bitbucket.org/scoobadog/tampermonkey/raw/master/planmill-login-redirect.js
// @include      /^https://online\.planmill\.com/.+/.+$/
// @grant        none
// @run-at       document-body
// ==/UserScript==
var path = window.location.pathname;
if (document.getElementById("logindiv") !== null
	|| path.endsWith("j_security_check")) {

	var url = window.location.href
		.replace(path, path.substr(0, path.indexOf("/", 1)))
		.replace(window.location.search, "") + "/";

	if (url.length < window.location.href.length) {
		window.location.replace(url)
	}
}
<|endoftext|>