Add CLI flag for debugging comment attachment issues (#10124)

<|original_code|>
    ) {
      if (locStart(comment) - locStart(ast) <= 0) {
        addLeadingComment(ast, comment);
        continue;
      }
      if (locEnd(comment) - locEnd(ast) >= 0) {
        addTrailingComment(ast, comment);
        continue;
      }
    }

    let args;
    if (avoidAstMutation) {
      args = [context];
    } else {
      comment.enclosingNode = enclosingNode;
      comment.precedingNode = precedingNode;
      comment.followingNode = followingNode;
      args = [comment, text, options, ast, isLastComment];
    }

    if (isOwnLineComment(text, options, decoratedComments, index)) {
      // If a comment exists on its own line, prefer a leading comment.
      // We also need to check if it's the first line of the file.
      if (handleOwnLineComment(...args)) {
        // We're good
      } else if (followingNode) {
        // Always a leading comment.
        addLeadingComment(followingNode, comment);
      } else if (precedingNode) {
        addTrailingComment(precedingNode, comment);
      } else if (enclosingNode) {
        addDanglingComment(enclosingNode, comment);
      } else {
        // There are no nodes, let's attach it to the root of the ast
        /* istanbul ignore next */
        addDanglingComment(ast, comment);
      }
    } else if (isEndOfLineComment(text, options, decoratedComments, index)) {
      if (handleEndOfLineComment(...args)) {
        // We're good
      } else if (precedingNode) {
        // There is content before this comment on the same line, but
        // none after it, so prefer a trailing comment of the previous node.
        addTrailingComment(precedingNode, comment);
      } else if (followingNode) {
        addLeadingComment(followingNode, comment);
      } else if (enclosingNode) {
        addDanglingComment(enclosingNode, comment);
      } else {
        // There are no nodes, let's attach it to the root of the ast
        /* istanbul ignore next */
        addDanglingComment(ast, comment);
      }
    } else {
      if (handleRemainingComment(...args)) {
        // We're good
      } else if (precedingNode && followingNode) {
        // Otherwise, text exists both before and after the comment on
        // the same line. If there is both a preceding and following
        // node, use a tie-breaking algorithm to determine if it should
        // be attached to the next or previous node. In the last case,
        // simply attach the right node;
        const tieCount = tiesToBreak.length;
        if (tieCount > 0) {
          const lastTie = tiesToBreak[tieCount - 1];
          if (lastTie.followingNode !== followingNode) {
            breakTies(tiesToBreak, text, options);
          }
        }
        tiesToBreak.push(context);
      } else if (precedingNode) {
        addTrailingComment(precedingNode, comment);
      } else if (followingNode) {
        addLeadingComment(followingNode, comment);
      } else if (enclosingNode) {
        addDanglingComment(enclosingNode, comment);
      } else {
        // There are no nodes, let's attach it to the root of the ast
<|edits_diff|>
--- src/main/comments.js
+++ src/main/comments.js
@@ -20,6 +20,7 @@
     }

     if (isOwnLineComment(text, options, decoratedComments, index)) {
+      comment.placement = "ownLine";
       // If a comment exists on its own line, prefer a leading comment.
       // We also need to check if it's the first line of the file.
       if (handleOwnLineComment(...args)) {
@@ -37,6 +38,7 @@
         addDanglingComment(ast, comment);
       }
     } else if (isEndOfLineComment(text, options, decoratedComments, index)) {
+      comment.placement = "endOfLine";
       if (handleEndOfLineComment(...args)) {
         // We're good
       } else if (precedingNode) {
<|current_version|>
    ) {
      if (locStart(comment) - locStart(ast) <= 0) {
        addLeadingComment(ast, comment);
        continue;
      }
      if (locEnd(comment) - locEnd(ast) >= 0) {
        addTrailingComment(ast, comment);
        continue;
      }
    }

    let args;
    if (avoidAstMutation) {
      args = [context];
    } else {
      comment.enclosingNode = enclosingNode;
      comment.precedingNode = precedingNode;
      comment.followingNode = followingNode;
      args = [comment, text, options, ast, isLastComment];
    }

    if (isOwnLineComment(text, options, decoratedComments, index)) {
      comment.placement = "ownLine";
      // If a comment exists on its own line, prefer a leading comment.
      // We also need to check if it's the first line of the file.
      if (handleOwnLineComment(...args)) {
        // We're good
      } else if (followingNode) {
        // Always a leading comment.
        addLeadingComment(followingNode, comment);
      } else if (precedingNode) {
        addTrailingComment(precedingNode, comment);
      } else if (enclosingNode) {
        addDanglingComment(enclosingNode, comment);
      } else {
        // There are no nodes, let's attach it to the root of the ast
        /* istanbul ignore next */
        addDanglingComment(ast, comment);
      }
    } else if (isEndOfLineComment(text, options, decoratedComments, index)) {
      comment.placement = "endOfLine";
      if (handleEndOfLineComment(...args)) {
        // We're good
      } else if (precedingNode) {
        // There is content before this comment on the same line, but
        // none after it, so prefer a trailing comment of the previous node.
        addTrailingComment(precedingNode, comment);
      } else if (followingNode) {
        addLeadingComment(followingNode, comment);
      } else if (enclosingNode) {
        addDanglingComment(enclosingNode, comment);
      } else {
        // There are no nodes, let's attach it to the root of the ast
        /* istanbul ignore next */
        addDanglingComment(ast, comment);
      }
    } else {
      if (handleRemainingComment(...args)) {
        // We're good
      } else if (precedingNode && followingNode) {
        // Otherwise, text exists both before and after the comment on
        // the same line. If there is both a preceding and following
        // node, use a tie-breaking algorithm to determine if it should
        // be attached to the next or previous node. In the last case,
        // simply attach the right node;
        const tieCount = tiesToBreak.length;
        if (tieCount > 0) {
          const lastTie = tiesToBreak[tieCount - 1];
          if (lastTie.followingNode !== followingNode) {
            breakTies(tiesToBreak, text, options);
          }
        }
        tiesToBreak.push(context);
      } else if (precedingNode) {
        addTrailingComment(precedingNode, comment);
      } else if (followingNode) {
        addLeadingComment(followingNode, comment);
      } else if (enclosingNode) {
        addDanglingComment(enclosingNode, comment);
      } else {
        // There are no nodes, let's attach it to the root of the ast
<|next_version|>
    ) {
      if (locStart(comment) - locStart(ast) <= 0) {
        addLeadingComment(ast, comment);
        continue;
      }
      if (locEnd(comment) - locEnd(ast) >= 0) {
        addTrailingComment(ast, comment);
        continue;
      }
    }

    let args;
    if (avoidAstMutation) {
      args = [context];
    } else {
      comment.enclosingNode = enclosingNode;
      comment.precedingNode = precedingNode;
      comment.followingNode = followingNode;
      args = [comment, text, options, ast, isLastComment];
    }

    if (isOwnLineComment(text, options, decoratedComments, index)) {
      comment.placement = "ownLine";
      // If a comment exists on its own line, prefer a leading comment.
      // We also need to check if it's the first line of the file.
      if (handleOwnLineComment(...args)) {
        // We're good
      } else if (followingNode) {
        // Always a leading comment.
        addLeadingComment(followingNode, comment);
      } else if (precedingNode) {
        addTrailingComment(precedingNode, comment);
      } else if (enclosingNode) {
        addDanglingComment(enclosingNode, comment);
      } else {
        // There are no nodes, let's attach it to the root of the ast
        /* istanbul ignore next */
        addDanglingComment(ast, comment);
      }
    } else if (isEndOfLineComment(text, options, decoratedComments, index)) {
      comment.placement = "endOfLine";
      if (handleEndOfLineComment(...args)) {
        // We're good
      } else if (precedingNode) {
        // There is content before this comment on the same line, but
        // none after it, so prefer a trailing comment of the previous node.
        addTrailingComment(precedingNode, comment);
      } else if (followingNode) {
        addLeadingComment(followingNode, comment);
      } else if (enclosingNode) {
        addDanglingComment(enclosingNode, comment);
      } else {
        // There are no nodes, let's attach it to the root of the ast
        /* istanbul ignore next */
        addDanglingComment(ast, comment);
      }
    } else {
      comment.placement = "remaining";
      if (handleRemainingComment(...args)) {
        // We're good
      } else if (precedingNode && followingNode) {
        // Otherwise, text exists both before and after the comment on
        // the same line. If there is both a preceding and following
        // node, use a tie-breaking algorithm to determine if it should
        // be attached to the next or previous node. In the last case,
        // simply attach the right node;
        const tieCount = tiesToBreak.length;
        if (tieCount > 0) {
          const lastTie = tiesToBreak[tieCount - 1];
          if (lastTie.followingNode !== followingNode) {
            breakTies(tiesToBreak, text, options);
          }
        }
        tiesToBreak.push(context);
      } else if (precedingNode) {
        addTrailingComment(precedingNode, comment);
      } else if (followingNode) {
        addLeadingComment(followingNode, comment);
      } else if (enclosingNode) {
        addDanglingComment(enclosingNode, comment);
      } else {
        // There are no nodes, let's attach it to the root of the ast


Add `espree` parser (#9000)

<|original_code|>
run_spec(__dirname, ["babel"], {
  quoteProps: "as-needed",
});

run_spec(__dirname, ["babel"], {
  quoteProps: "preserve",
});

run_spec(__dirname, ["babel"], {
  quoteProps: "consistent",
});

run_spec(__dirname, ["babel"], {
  quoteProps: "consistent",
  singleQuote: true,
});

<|edits_diff|>
--- tests/js/quote-props/jsfmt.spec.js
+++ tests/js/quote-props/jsfmt.spec.js
@@ -1,13 +1,18 @@
+const errors = { espree: ["classes.js"] };
+
 run_spec(__dirname, ["babel"], {
   quoteProps: "as-needed",
+  errors,
 });

 run_spec(__dirname, ["babel"], {
   quoteProps: "preserve",
+  errors,
 });

 run_spec(__dirname, ["babel"], {
   quoteProps: "consistent",
+  errors,
 });

 run_spec(__dirname, ["babel"], {
<|current_version|>
const errors = { espree: ["classes.js"] };

run_spec(__dirname, ["babel"], {
  quoteProps: "as-needed",
  errors,
});

run_spec(__dirname, ["babel"], {
  quoteProps: "preserve",
  errors,
});

run_spec(__dirname, ["babel"], {
  quoteProps: "consistent",
  errors,
});

run_spec(__dirname, ["babel"], {
  quoteProps: "consistent",
  singleQuote: true,
});

<|next_version|>
const errors = { espree: ["classes.js"] };

run_spec(__dirname, ["babel"], {
  quoteProps: "as-needed",
  errors,
});

run_spec(__dirname, ["babel"], {
  quoteProps: "preserve",
  errors,
});

run_spec(__dirname, ["babel"], {
  quoteProps: "consistent",
  errors,
});

run_spec(__dirname, ["babel"], {
  quoteProps: "consistent",
  singleQuote: true,
  errors,
});


Add feature to test idempotency in playground

<|original_code|>
    return false;
  }
};
// eslint-disable-next-line
fs = module$1 = module = path = os = crypto = {};
self.process = { argv: [], env: { PRETTIER_DEBUG: true } };
self.assert = { ok: function() {}, strictEqual: function() {} };
self.require = function require(path) {
  return self[path.replace(/.+-/, "")];
};

importScripts("lib/index.js");
var prettier = index; // eslint-disable-line

var parsersLoaded = {};

self.onmessage = function(message) {
  var options = message.data.options || {};
  options.parser = options.parser || "babylon";

  delete options.ast;
  delete options.doc;

  var formatted = formatCode(message.data.text, options);
  var doc;
  var ast;

  if (message.data.ast) {
    var actualAst;
    var errored = false;
    try {
      actualAst = prettier.__debug.parse(message.data.text, options);
      ast = JSON.stringify(actualAst);
    } catch (e) {
      errored = true;
      ast = String(e);
    }
    if (!errored) {
      try {
        ast = formatCode(ast, { parser: "json" });
      } catch (e) {
        ast = JSON.stringify(actualAst, null, 2);
      }
    }
  }

  if (message.data.doc) {
    lazyLoadParser("babylon");
    try {
      doc = prettier.__debug.formatDoc(
        prettier.__debug.printToDoc(message.data.text, options),
        { parser: "babylon" }
      );
    } catch (e) {
      doc = String(e);
    }
  }

  self.postMessage({
    formatted: formatted,
    doc: doc,
    ast: ast,
    version: prettier.version
  });
};

function formatCode(text, options) {
  lazyLoadParser(options.parser);
  try {
    return prettier.format(text, options);
  } catch (e) {
    // Multiparser may throw if we haven't loaded the right parser
    // Load it lazily and retry!
    if (e.parser && !parsersLoaded[e.parser]) {
      lazyLoadParser(e.parser);
      return formatCode(text, options);
    }
    return String(e);
  }
}

function lazyLoadParser(parser) {
  var script =
    parser === "json" ? "parser-babylon.js" : "parser-" + parser + ".js";

  if (!parsersLoaded[parser]) {
<|edits_diff|>
--- website/static/worker.js
+++ website/static/worker.js
@@ -20,10 +20,12 @@

   delete options.ast;
   delete options.doc;
+  delete options.output2;

   var formatted = formatCode(message.data.text, options);
   var doc;
   var ast;
+  var formatted2;

   if (message.data.ast) {
     var actualAst;
@@ -56,6 +58,10 @@
     }
   }

+  if (message.data.formatted2) {
+    formatted2 = formatCode(formatted, options);
+  }
+
   self.postMessage({
     formatted: formatted,
     doc: doc,
<|current_version|>
    return false;
  }
};
// eslint-disable-next-line
fs = module$1 = module = path = os = crypto = {};
self.process = { argv: [], env: { PRETTIER_DEBUG: true } };
self.assert = { ok: function() {}, strictEqual: function() {} };
self.require = function require(path) {
  return self[path.replace(/.+-/, "")];
};

importScripts("lib/index.js");
var prettier = index; // eslint-disable-line

var parsersLoaded = {};

self.onmessage = function(message) {
  var options = message.data.options || {};
  options.parser = options.parser || "babylon";

  delete options.ast;
  delete options.doc;
  delete options.output2;

  var formatted = formatCode(message.data.text, options);
  var doc;
  var ast;
  var formatted2;

  if (message.data.ast) {
    var actualAst;
    var errored = false;
    try {
      actualAst = prettier.__debug.parse(message.data.text, options);
      ast = JSON.stringify(actualAst);
    } catch (e) {
      errored = true;
      ast = String(e);
    }
    if (!errored) {
      try {
        ast = formatCode(ast, { parser: "json" });
      } catch (e) {
        ast = JSON.stringify(actualAst, null, 2);
      }
    }
  }

  if (message.data.doc) {
    lazyLoadParser("babylon");
    try {
      doc = prettier.__debug.formatDoc(
        prettier.__debug.printToDoc(message.data.text, options),
        { parser: "babylon" }
      );
    } catch (e) {
      doc = String(e);
    }
  }

  if (message.data.formatted2) {
    formatted2 = formatCode(formatted, options);
  }

  self.postMessage({
    formatted: formatted,
    doc: doc,
    ast: ast,
    version: prettier.version
  });
};

function formatCode(text, options) {
  lazyLoadParser(options.parser);
  try {
    return prettier.format(text, options);
  } catch (e) {
    // Multiparser may throw if we haven't loaded the right parser
    // Load it lazily and retry!
    if (e.parser && !parsersLoaded[e.parser]) {
      lazyLoadParser(e.parser);
      return formatCode(text, options);
    }
    return String(e);
  }
}

function lazyLoadParser(parser) {
  var script =
    parser === "json" ? "parser-babylon.js" : "parser-" + parser + ".js";

  if (!parsersLoaded[parser]) {
<|next_version|>
    return false;
  }
};
// eslint-disable-next-line
fs = module$1 = module = path = os = crypto = {};
self.process = { argv: [], env: { PRETTIER_DEBUG: true } };
self.assert = { ok: function() {}, strictEqual: function() {} };
self.require = function require(path) {
  return self[path.replace(/.+-/, "")];
};

importScripts("lib/index.js");
var prettier = index; // eslint-disable-line

var parsersLoaded = {};

self.onmessage = function(message) {
  var options = message.data.options || {};
  options.parser = options.parser || "babylon";

  delete options.ast;
  delete options.doc;
  delete options.output2;

  var formatted = formatCode(message.data.text, options);
  var doc;
  var ast;
  var formatted2;

  if (message.data.ast) {
    var actualAst;
    var errored = false;
    try {
      actualAst = prettier.__debug.parse(message.data.text, options);
      ast = JSON.stringify(actualAst);
    } catch (e) {
      errored = true;
      ast = String(e);
    }
    if (!errored) {
      try {
        ast = formatCode(ast, { parser: "json" });
      } catch (e) {
        ast = JSON.stringify(actualAst, null, 2);
      }
    }
  }

  if (message.data.doc) {
    lazyLoadParser("babylon");
    try {
      doc = prettier.__debug.formatDoc(
        prettier.__debug.printToDoc(message.data.text, options),
        { parser: "babylon" }
      );
    } catch (e) {
      doc = String(e);
    }
  }

  if (message.data.formatted2) {
    formatted2 = formatCode(formatted, options);
  }

  self.postMessage({
    formatted: formatted,
    doc: doc,
    ast: ast,
    formatted2: formatted2,
    version: prettier.version
  });
};

function formatCode(text, options) {
  lazyLoadParser(options.parser);
  try {
    return prettier.format(text, options);
  } catch (e) {
    // Multiparser may throw if we haven't loaded the right parser
    // Load it lazily and retry!
    if (e.parser && !parsersLoaded[e.parser]) {
      lazyLoadParser(e.parser);
      return formatCode(text, options);
    }
    return String(e);
  }
}

function lazyLoadParser(parser) {
  var script =
    parser === "json" ? "parser-babylon.js" : "parser-" + parser + ".js";

  if (!parsersLoaded[parser]) {


Fix handling very large stacks of sync middleware

<|original_code|>

  // append automatic head
  if (this.methods.get && !this.methods.head) {
    methods.push('head');
  }

  for (var i = 0; i < methods.length; i++) {
    // make upper case
    methods[i] = methods[i].toUpperCase();
  }

  return methods;
};

/**
 * dispatch req, res into this route
 * @private
 */

Route.prototype.dispatch = function dispatch(req, res, done) {
  var idx = 0;
  var stack = this.stack;
  if (stack.length === 0) {
    return done();
  }

  var method = req.method.toLowerCase();
  if (method === 'head' && !this.methods['head']) {
    method = 'get';
  }

  req.route = this;

  next();

  function next(err) {
    // signal to exit route
    if (err && err === 'route') {
      return done();
    }

    // signal to exit router
    if (err && err === 'router') {
      return done(err)
    }

    var layer = stack[idx++];
    if (!layer) {
      return done(err);
    }

    if (layer.method && layer.method !== method) {
      return next(err);
    }

    if (err) {
      layer.handle_error(err, req, res, next);
    } else {
      layer.handle_request(req, res, next);
    }
  }
};

/**
 * Add a handler for all HTTP verbs to this route.
 *
 * Behaves just like middleware and can respond or call `next`
 * to continue processing.
 *
 * You can use multiple `.all` call to add multiple handlers.
 *
 *   function check_something(req, res, next){
 *     next();
 *   };
 *
 *   function validate_user(req, res, next){
 *     next();
 *   };
 *
 *   route
 *   .all(validate_user)
 *   .all(check_something)
 *   .get(function(req, res, next){
 *     res.send('hello world');
<|edits_diff|>
--- lib/router/route.js
+++ lib/router/route.js
@@ -20,6 +20,8 @@
 Route.prototype.dispatch = function dispatch(req, res, done) {
   var idx = 0;
   var stack = this.stack;
+  var sync = 0
+
   if (stack.length === 0) {
     return done();
   }
@@ -47,6 +49,11 @@
     var layer = stack[idx++];
     if (!layer) {
       return done(err);
+    }
+
+    // max sync stack
+    if (++sync > 100) {
+      return setImmediate(next, err)
     }

     if (layer.method && layer.method !== method) {
<|current_version|>

  // append automatic head
  if (this.methods.get && !this.methods.head) {
    methods.push('head');
  }

  for (var i = 0; i < methods.length; i++) {
    // make upper case
    methods[i] = methods[i].toUpperCase();
  }

  return methods;
};

/**
 * dispatch req, res into this route
 * @private
 */

Route.prototype.dispatch = function dispatch(req, res, done) {
  var idx = 0;
  var stack = this.stack;
  var sync = 0

  if (stack.length === 0) {
    return done();
  }

  var method = req.method.toLowerCase();
  if (method === 'head' && !this.methods['head']) {
    method = 'get';
  }

  req.route = this;

  next();

  function next(err) {
    // signal to exit route
    if (err && err === 'route') {
      return done();
    }

    // signal to exit router
    if (err && err === 'router') {
      return done(err)
    }

    var layer = stack[idx++];
    if (!layer) {
      return done(err);
    }

    // max sync stack
    if (++sync > 100) {
      return setImmediate(next, err)
    }

    if (layer.method && layer.method !== method) {
      return next(err);
    }

    if (err) {
      layer.handle_error(err, req, res, next);
    } else {
      layer.handle_request(req, res, next);
    }
  }
};

/**
 * Add a handler for all HTTP verbs to this route.
 *
 * Behaves just like middleware and can respond or call `next`
 * to continue processing.
 *
 * You can use multiple `.all` call to add multiple handlers.
 *
 *   function check_something(req, res, next){
 *     next();
 *   };
 *
 *   function validate_user(req, res, next){
 *     next();
 *   };
 *
 *   route
 *   .all(validate_user)
 *   .all(check_something)
 *   .get(function(req, res, next){
 *     res.send('hello world');
<|next_version|>

  // append automatic head
  if (this.methods.get && !this.methods.head) {
    methods.push('head');
  }

  for (var i = 0; i < methods.length; i++) {
    // make upper case
    methods[i] = methods[i].toUpperCase();
  }

  return methods;
};

/**
 * dispatch req, res into this route
 * @private
 */

Route.prototype.dispatch = function dispatch(req, res, done) {
  var idx = 0;
  var stack = this.stack;
  var sync = 0

  if (stack.length === 0) {
    return done();
  }

  var method = req.method.toLowerCase();
  if (method === 'head' && !this.methods['head']) {
    method = 'get';
  }

  req.route = this;

  next();

  function next(err) {
    // signal to exit route
    if (err && err === 'route') {
      return done();
    }

    // signal to exit router
    if (err && err === 'router') {
      return done(err)
    }

    var layer = stack[idx++];
    if (!layer) {
      return done(err);
    }

    // max sync stack
    if (++sync > 100) {
      return setImmediate(next, err)
    }

    if (layer.method && layer.method !== method) {
      return next(err);
    }

    if (err) {
      layer.handle_error(err, req, res, next);
    } else {
      layer.handle_request(req, res, next);
    }

    sync = 0
  }
};

/**
 * Add a handler for all HTTP verbs to this route.
 *
 * Behaves just like middleware and can respond or call `next`
 * to continue processing.
 *
 * You can use multiple `.all` call to add multiple handlers.
 *
 *   function check_something(req, res, next){
 *     next();
 *   };
 *
 *   function validate_user(req, res, next){
 *     next();
 *   };
 *
 *   route
 *   .all(validate_user)
 *   .all(check_something)
 *   .get(function(req, res, next){
 *     res.send('hello world');


expose router

<|original_code|>

/*!
 * Express
 * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var http = require('http')
  , connect = require('connect')
  , proto = require('./application')
  , Route = require('./router/route')
  , req = require('./request')
  , res = require('./response')
  , utils = connect.utils;

/**
 * Expose `createApplication()`.
 */

exports = module.exports = createApplication;

/**
 * Framework version.
 */

exports.version = '3.0.0alpha1-pre';

/**
 * Create an express application.
 *
 * @return {Function}
 * @api public
 */

function createApplication() {
  var app = connect();
  utils.merge(app, proto);
  app.request = { __proto__: req };
  app.response = { __proto__: res };
  app.init();
  return app;
}

/**
 * Expose connect.middleware as express.*
 * for example `express.logger` etc.
 */

for (var key in connect.middleware) {
  Object.defineProperty(
      exports
    , key
    , Object.getOwnPropertyDescriptor(connect.middleware, key));
}

/**
 * Expose the prototypes.
 */

exports.application = proto;
exports.request = req;
exports.response = res;

/**
 * Expose constructors.
 */

exports.Route = Route;

/**
 * Expose HTTP methods.
 */

exports.methods = require('./router/methods');

// Error handler title

exports.errorHandler.title = 'Express';

<|edits_diff|>
--- lib/express.js
+++ lib/express.js
@@ -13,6 +13,7 @@
   , connect = require('connect')
   , proto = require('./application')
   , Route = require('./router/route')
+  , Router = require('./router')
   , req = require('./request')
   , res = require('./response')
   , utils = connect.utils;
<|current_version|>

/*!
 * Express
 * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var http = require('http')
  , connect = require('connect')
  , proto = require('./application')
  , Route = require('./router/route')
  , Router = require('./router')
  , req = require('./request')
  , res = require('./response')
  , utils = connect.utils;

/**
 * Expose `createApplication()`.
 */

exports = module.exports = createApplication;

/**
 * Framework version.
 */

exports.version = '3.0.0alpha1-pre';

/**
 * Create an express application.
 *
 * @return {Function}
 * @api public
 */

function createApplication() {
  var app = connect();
  utils.merge(app, proto);
  app.request = { __proto__: req };
  app.response = { __proto__: res };
  app.init();
  return app;
}

/**
 * Expose connect.middleware as express.*
 * for example `express.logger` etc.
 */

for (var key in connect.middleware) {
  Object.defineProperty(
      exports
    , key
    , Object.getOwnPropertyDescriptor(connect.middleware, key));
}

/**
 * Expose the prototypes.
 */

exports.application = proto;
exports.request = req;
exports.response = res;

/**
 * Expose constructors.
 */

exports.Route = Route;

/**
 * Expose HTTP methods.
 */

exports.methods = require('./router/methods');

// Error handler title

exports.errorHandler.title = 'Express';

<|next_version|>

/*!
 * Express
 * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var http = require('http')
  , connect = require('connect')
  , proto = require('./application')
  , Route = require('./router/route')
  , Router = require('./router')
  , req = require('./request')
  , res = require('./response')
  , utils = connect.utils;

/**
 * Expose `createApplication()`.
 */

exports = module.exports = createApplication;

/**
 * Framework version.
 */

exports.version = '3.0.0alpha1-pre';

/**
 * Create an express application.
 *
 * @return {Function}
 * @api public
 */

function createApplication() {
  var app = connect();
  utils.merge(app, proto);
  app.request = { __proto__: req };
  app.response = { __proto__: res };
  app.init();
  return app;
}

/**
 * Expose connect.middleware as express.*
 * for example `express.logger` etc.
 */

for (var key in connect.middleware) {
  Object.defineProperty(
      exports
    , key
    , Object.getOwnPropertyDescriptor(connect.middleware, key));
}

/**
 * Expose the prototypes.
 */

exports.application = proto;
exports.request = req;
exports.response = res;

/**
 * Expose constructors.
 */

exports.Route = Route;
exports.Router = Router;

/**
 * Expose HTTP methods.
 */

exports.methods = require('./router/methods');

// Error handler title

exports.errorHandler.title = 'Express';


res.send() as 204. Closes #419

<|original_code|>
        app.get('/json', function(req, res){
            res.header('X-Foo', 'bar');
            res.send({ foo: 'bar' }, { 'X-Foo': 'baz' }, 201);
        });

        app.get('/text', function(req, res){
            res.header('X-Foo', 'bar');
            res.contentType('.txt');
            res.send('wahoo');
        });

        app.get('/status', function(req, res){
            res.send(404);
        });

        app.get('/error', function(req, res){
            res.send('Oh shit!', { 'Content-Type': 'text/plain' }, 500);
        });

        app.get('/buffer', function(req, res){
            res.send(new Buffer('wahoo!'));
        });

        assert.response(app,
            { url: '/html' },
            { body: '
test
', headers: { 'Content-Language': 'en', 'Content-Type': 'text/html; charset=utf-8' }});
        assert.response(app,
            { url: '/json' },
            { body: '{"foo":"bar"}', status: 201, headers: { 'Content-Type': 'application/json', 'X-Foo': 'baz' }});
        assert.response(app,
            { url: '/text' },
            { body: 'wahoo', headers: { 'Content-Type': 'text/plain; charset=utf-8', 'X-Foo': 'bar' }});
        assert.response(app,
            { url: '/status' },
            { body: 'Not Found', status: 404, headers: { 'Content-Type': 'text/plain; charset=utf-8' }});
        assert.response(app,
            { url: '/error' },
            { body: 'Oh shit!', status: 500, headers: { 'Content-Type': 'text/plain' }});
        assert.response(app,
            { url: '/buffer' },
            { body: 'wahoo!', headers: { 'Content-Type': 'application/octet-stream' }});
    },

    'test #contentType()': function(assert){
        var app = express.createServer();

        app.get('/html', function(req, res){
            res.contentType('index.html');
            res.writeHead(200, res.headers);
            res.end('
yay
');
        });

        assert.response(app,
            { url: '/html' },
            { body: '
yay
', headers: { 'Content-Type': 'text/html; charset=utf-8' }});
    },

    'test #attachment()': function(assert){
        var app = express.createServer();

        app.get('/style.css', function(req, res){
            res.attachment();
            res.send('some stylezzz');
        });

<|edits_diff|>
--- test/response.test.js
+++ test/response.test.js
@@ -19,6 +19,10 @@

         app.get('/buffer', function(req, res){
             res.send(new Buffer('wahoo!'));
+        });
+
+        app.get('/noargs', function(req, res, next){
+            res.send();
         });

         assert.response(app,
<|current_version|>
        app.get('/json', function(req, res){
            res.header('X-Foo', 'bar');
            res.send({ foo: 'bar' }, { 'X-Foo': 'baz' }, 201);
        });

        app.get('/text', function(req, res){
            res.header('X-Foo', 'bar');
            res.contentType('.txt');
            res.send('wahoo');
        });

        app.get('/status', function(req, res){
            res.send(404);
        });

        app.get('/error', function(req, res){
            res.send('Oh shit!', { 'Content-Type': 'text/plain' }, 500);
        });

        app.get('/buffer', function(req, res){
            res.send(new Buffer('wahoo!'));
        });

        app.get('/noargs', function(req, res, next){
            res.send();
        });

        assert.response(app,
            { url: '/html' },
            { body: '
test
', headers: { 'Content-Language': 'en', 'Content-Type': 'text/html; charset=utf-8' }});
        assert.response(app,
            { url: '/json' },
            { body: '{"foo":"bar"}', status: 201, headers: { 'Content-Type': 'application/json', 'X-Foo': 'baz' }});
        assert.response(app,
            { url: '/text' },
            { body: 'wahoo', headers: { 'Content-Type': 'text/plain; charset=utf-8', 'X-Foo': 'bar' }});
        assert.response(app,
            { url: '/status' },
            { body: 'Not Found', status: 404, headers: { 'Content-Type': 'text/plain; charset=utf-8' }});
        assert.response(app,
            { url: '/error' },
            { body: 'Oh shit!', status: 500, headers: { 'Content-Type': 'text/plain' }});
        assert.response(app,
            { url: '/buffer' },
            { body: 'wahoo!', headers: { 'Content-Type': 'application/octet-stream' }});
    },

    'test #contentType()': function(assert){
        var app = express.createServer();

        app.get('/html', function(req, res){
            res.contentType('index.html');
            res.writeHead(200, res.headers);
            res.end('
yay
');
        });

        assert.response(app,
            { url: '/html' },
            { body: '
yay
', headers: { 'Content-Type': 'text/html; charset=utf-8' }});
    },

    'test #attachment()': function(assert){
        var app = express.createServer();

        app.get('/style.css', function(req, res){
            res.attachment();
            res.send('some stylezzz');
        });

<|next_version|>
        app.get('/json', function(req, res){
            res.header('X-Foo', 'bar');
            res.send({ foo: 'bar' }, { 'X-Foo': 'baz' }, 201);
        });

        app.get('/text', function(req, res){
            res.header('X-Foo', 'bar');
            res.contentType('.txt');
            res.send('wahoo');
        });

        app.get('/status', function(req, res){
            res.send(404);
        });

        app.get('/error', function(req, res){
            res.send('Oh shit!', { 'Content-Type': 'text/plain' }, 500);
        });

        app.get('/buffer', function(req, res){
            res.send(new Buffer('wahoo!'));
        });

        app.get('/noargs', function(req, res, next){
            res.send();
        });

        assert.response(app,
            { url: '/html' },
            { body: '
test
', headers: { 'Content-Language': 'en', 'Content-Type': 'text/html; charset=utf-8' }});
        assert.response(app,
            { url: '/json' },
            { body: '{"foo":"bar"}', status: 201, headers: { 'Content-Type': 'application/json', 'X-Foo': 'baz' }});
        assert.response(app,
            { url: '/text' },
            { body: 'wahoo', headers: { 'Content-Type': 'text/plain; charset=utf-8', 'X-Foo': 'bar' }});
        assert.response(app,
            { url: '/status' },
            { body: 'Not Found', status: 404, headers: { 'Content-Type': 'text/plain; charset=utf-8' }});
        assert.response(app,
            { url: '/error' },
            { body: 'Oh shit!', status: 500, headers: { 'Content-Type': 'text/plain' }});
        assert.response(app,
            { url: '/buffer' },
            { body: 'wahoo!', headers: { 'Content-Type': 'application/octet-stream' }});
        assert.response(app,
            { url: '/noargs' },
            { status: 204 });
    },

    'test #contentType()': function(assert){
        var app = express.createServer();

        app.get('/html', function(req, res){
            res.contentType('index.html');
            res.writeHead(200, res.headers);
            res.end('
yay
');
        });

        assert.response(app,
            { url: '/html' },
            { body: '
yay
', headers: { 'Content-Type': 'text/html; charset=utf-8' }});
    },

    'test #attachment()': function(assert){
        var app = express.createServer();

        app.get('/style.css', function(req, res){
            res.attachment();
            res.send('some stylezzz');
        });


Added mockRequest() and mockResponse()

<|original_code|>
  var promise = node.fs.cat(path, "utf8")
  promise.addErrback(function(){ throw "failed to read file `" + path + "'" })
  promise.addCallback(function(contents){
    setTimeout(function(){
      if (__loading__[0] == path)
        __loading__.shift(), callback(contents)
      else
        setTimeout(arguments.callee, 50)
    }, 50)
  })
}

load = function(path) {
  readFile(path, function(contents){
    eval(contents)
  })
}

load('/Users/tjholowaychuk/scripts/gems/JSpec/lib/jspec.js')
load('lib/express.core.js')
load('lib/express.mime.js')
load('lib/express.view.js')

setTimeout(function(){
  JSpec
  .exec('spec/spec.core.js')
  .exec('spec/spec.routing.js')
  .exec('spec/spec.mime.js')
  .exec('spec/spec.view.js')
  setTimeout(function(){
    JSpec.run({ formatter : JSpec.formatters.Terminal, failuresOnly : true })
    setTimeout(function() {
      JSpec.report()
    }, __loadDelay__ / 3)
  }, __loadDelay__ / 3)
}, __loadDelay__ / 3)

<|edits_diff|>
--- spec/spec.node.js
+++ spec/spec.node.js
@@ -20,6 +20,7 @@
 load('lib/express.core.js')
 load('lib/express.mime.js')
 load('lib/express.view.js')
+load('lib/express.spec.helpers.js')

 setTimeout(function(){
   JSpec
<|current_version|>
  var promise = node.fs.cat(path, "utf8")
  promise.addErrback(function(){ throw "failed to read file `" + path + "'" })
  promise.addCallback(function(contents){
    setTimeout(function(){
      if (__loading__[0] == path)
        __loading__.shift(), callback(contents)
      else
        setTimeout(arguments.callee, 50)
    }, 50)
  })
}

load = function(path) {
  readFile(path, function(contents){
    eval(contents)
  })
}

load('/Users/tjholowaychuk/scripts/gems/JSpec/lib/jspec.js')
load('lib/express.core.js')
load('lib/express.mime.js')
load('lib/express.view.js')
load('lib/express.spec.helpers.js')

setTimeout(function(){
  JSpec
  .exec('spec/spec.core.js')
  .exec('spec/spec.routing.js')
  .exec('spec/spec.mime.js')
  .exec('spec/spec.view.js')
  setTimeout(function(){
    JSpec.run({ formatter : JSpec.formatters.Terminal, failuresOnly : true })
    setTimeout(function() {
      JSpec.report()
    }, __loadDelay__ / 3)
  }, __loadDelay__ / 3)
}, __loadDelay__ / 3)

<|next_version|>
  var promise = node.fs.cat(path, "utf8")
  promise.addErrback(function(){ throw "failed to read file `" + path + "'" })
  promise.addCallback(function(contents){
    setTimeout(function(){
      if (__loading__[0] == path)
        __loading__.shift(), callback(contents)
      else
        setTimeout(arguments.callee, 50)
    }, 50)
  })
}

load = function(path) {
  readFile(path, function(contents){
    eval(contents)
  })
}

load('/Users/tjholowaychuk/scripts/gems/JSpec/lib/jspec.js')
load('lib/express.core.js')
load('lib/express.mime.js')
load('lib/express.view.js')
load('lib/express.spec.helpers.js')

setTimeout(function(){
  JSpec
  .exec('spec/spec.core.js')
  .exec('spec/spec.routing.js')
  .exec('spec/spec.mime.js')
  .exec('spec/spec.view.js')
  .exec('spec/spec.spec.helpers.js')
  setTimeout(function(){
    JSpec.run({ formatter : JSpec.formatters.Terminal, failuresOnly : true })
    setTimeout(function() {
      JSpec.report()
    }, __loadDelay__ / 3)
  }, __loadDelay__ / 3)
}, __loadDelay__ / 3)


Avoid using the values toString method in _.invert if it’s not a function. [closes #3260]

<|original_code|>
      return object != null && hasPath(object, path, baseHasIn);
    }

    /**
     * Creates an object composed of the inverted keys and values of `object`.
     * If `object` contains duplicate values, subsequent values overwrite
     * property assignments of previous values.
     *
     * @static
     * @memberOf _
     * @since 0.7.0
     * @category Object
     * @param {Object} object The object to invert.
     * @returns {Object} Returns the new inverted object.
     * @example
     *
     * var object = { 'a': 1, 'b': 2, 'c': 1 };
     *
     * _.invert(object);
     * // => { '1': 'c', '2': 'b' }
     */
    var invert = createInverter(function(result, value, key) {
      result[value] = key;
    }, constant(identity));

    /**
     * This method is like `_.invert` except that the inverted object is generated
     * from the results of running each element of `object` thru `iteratee`. The
     * corresponding inverted value of each inverted key is an array of keys
     * responsible for generating the inverted value. The iteratee is invoked
     * with one argument: (value).
     *
     * @static
     * @memberOf _
     * @since 4.1.0
     * @category Object
     * @param {Object} object The object to invert.
     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
     * @returns {Object} Returns the new inverted object.
     * @example
     *
     * var object = { 'a': 1, 'b': 2, 'c': 1 };
     *
     * _.invertBy(object);
     * // => { '1': ['a', 'c'], '2': ['b'] }
     *
     * _.invertBy(object, function(value) {
     *   return 'group' + value;
     * });
     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
     */
    var invertBy = createInverter(function(result, value, key) {
      if (hasOwnProperty.call(result, value)) {
        result[value].push(key);
      } else {
        result[value] = [key];
      }
    }, getIteratee);

    /**
     * Invokes the method at `path` of `object`.
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Object
     * @param {Object} object The object to query.
     * @param {Array|string} path The path of the method to invoke.
     * @param {...*} [args] The arguments to invoke the method with.
     * @returns {*} Returns the result of the invoked method.
     * @example
     *
     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
     *
     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
     * // => [2, 3]
<|edits_diff|>
--- lodash.js
+++ lodash.js
@@ -20,6 +20,11 @@
      * // => { '1': 'c', '2': 'b' }
      */
     var invert = createInverter(function(result, value, key) {
+      if (value != null &&
+          typeof value.toString != 'function') {
+        value = nativeObjectToString.call(value);
+      }
+
       result[value] = key;
     }, constant(identity));

<|current_version|>
      return object != null && hasPath(object, path, baseHasIn);
    }

    /**
     * Creates an object composed of the inverted keys and values of `object`.
     * If `object` contains duplicate values, subsequent values overwrite
     * property assignments of previous values.
     *
     * @static
     * @memberOf _
     * @since 0.7.0
     * @category Object
     * @param {Object} object The object to invert.
     * @returns {Object} Returns the new inverted object.
     * @example
     *
     * var object = { 'a': 1, 'b': 2, 'c': 1 };
     *
     * _.invert(object);
     * // => { '1': 'c', '2': 'b' }
     */
    var invert = createInverter(function(result, value, key) {
      if (value != null &&
          typeof value.toString != 'function') {
        value = nativeObjectToString.call(value);
      }

      result[value] = key;
    }, constant(identity));

    /**
     * This method is like `_.invert` except that the inverted object is generated
     * from the results of running each element of `object` thru `iteratee`. The
     * corresponding inverted value of each inverted key is an array of keys
     * responsible for generating the inverted value. The iteratee is invoked
     * with one argument: (value).
     *
     * @static
     * @memberOf _
     * @since 4.1.0
     * @category Object
     * @param {Object} object The object to invert.
     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
     * @returns {Object} Returns the new inverted object.
     * @example
     *
     * var object = { 'a': 1, 'b': 2, 'c': 1 };
     *
     * _.invertBy(object);
     * // => { '1': ['a', 'c'], '2': ['b'] }
     *
     * _.invertBy(object, function(value) {
     *   return 'group' + value;
     * });
     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
     */
    var invertBy = createInverter(function(result, value, key) {
      if (hasOwnProperty.call(result, value)) {
        result[value].push(key);
      } else {
        result[value] = [key];
      }
    }, getIteratee);

    /**
     * Invokes the method at `path` of `object`.
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Object
     * @param {Object} object The object to query.
     * @param {Array|string} path The path of the method to invoke.
     * @param {...*} [args] The arguments to invoke the method with.
     * @returns {*} Returns the result of the invoked method.
     * @example
     *
     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
     *
     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
     * // => [2, 3]
<|next_version|>
      return object != null && hasPath(object, path, baseHasIn);
    }

    /**
     * Creates an object composed of the inverted keys and values of `object`.
     * If `object` contains duplicate values, subsequent values overwrite
     * property assignments of previous values.
     *
     * @static
     * @memberOf _
     * @since 0.7.0
     * @category Object
     * @param {Object} object The object to invert.
     * @returns {Object} Returns the new inverted object.
     * @example
     *
     * var object = { 'a': 1, 'b': 2, 'c': 1 };
     *
     * _.invert(object);
     * // => { '1': 'c', '2': 'b' }
     */
    var invert = createInverter(function(result, value, key) {
      if (value != null &&
          typeof value.toString != 'function') {
        value = nativeObjectToString.call(value);
      }

      result[value] = key;
    }, constant(identity));

    /**
     * This method is like `_.invert` except that the inverted object is generated
     * from the results of running each element of `object` thru `iteratee`. The
     * corresponding inverted value of each inverted key is an array of keys
     * responsible for generating the inverted value. The iteratee is invoked
     * with one argument: (value).
     *
     * @static
     * @memberOf _
     * @since 4.1.0
     * @category Object
     * @param {Object} object The object to invert.
     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
     * @returns {Object} Returns the new inverted object.
     * @example
     *
     * var object = { 'a': 1, 'b': 2, 'c': 1 };
     *
     * _.invertBy(object);
     * // => { '1': ['a', 'c'], '2': ['b'] }
     *
     * _.invertBy(object, function(value) {
     *   return 'group' + value;
     * });
     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
     */
    var invertBy = createInverter(function(result, value, key) {
      if (value != null &&
          typeof value.toString != 'function') {
        value = nativeObjectToString.call(value);
      }

      if (hasOwnProperty.call(result, value)) {
        result[value].push(key);
      } else {
        result[value] = [key];
      }
    }, getIteratee);

    /**
     * Invokes the method at `path` of `object`.
     *
     * @static
     * @memberOf _
     * @since 4.0.0
     * @category Object
     * @param {Object} object The object to query.
     * @param {Array|string} path The path of the method to invoke.
     * @param {...*} [args] The arguments to invoke the method with.
     * @returns {*} Returns the result of the invoked method.
     * @example
     *
     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
     *
     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
     * // => [2, 3]


Add private tag to unexposed functions. [ci skip]

<|original_code|>
    fs = require('fs-extra'),
    path = require('path');

var file = require('../common/file'),
    mapping = require('../common/mapping'),
    util = require('../common/util');

var templatePath = path.join(__dirname, 'template/doc'),
    template = file.globTemplate(path.join(templatePath, '*.jst'));

var argNames = ['a', 'b', 'c', 'd'];

var templateData = {
  'mapping': mapping,
  'toArgOrder': toArgOrder,
  'toFuncList': toFuncList
};

/**
 * Converts arranged argument `indexes` into a named argument string
 * representation of their order.
 *
 * @param {number[]} indexes The arranged argument indexes.
 * @returns {string} Returns the named argument string.
 */
function toArgOrder(indexes) {
  var reordered = [];
  _.each(indexes, function(newIndex, index) {
    reordered[newIndex] = argNames[index];
  });
  return '`(' + reordered.join(', ') + ')`';
}

/**
 * Converts `funcNames` into a chunked list string representation.
 *
 * @param {string[]} funcNames The function names.
 * @returns {string} Returns the function list string.
 */
function toFuncList(funcNames) {
  var chunks = _.chunk(funcNames.slice().sort(), 5),
      lastChunk = _.last(chunks),
      last = lastChunk ? lastChunk.pop() : undefined;

  chunks = _.reject(chunks, _.isEmpty);
  lastChunk = _.last(chunks);

  var result = '`' + _.map(chunks, function(chunk) {
    return chunk.join('`, `') + '`';
  }).join(',\n`');

  if (last == null) {
    return result;
  }
  if (_.size(chunks) > 1 || _.size(lastChunk) > 1) {
    result += ',';
  }
  result += ' &';
  result += _.size(lastChunk) < 5 ? ' ' : '\n';
  return result + '`' + last + '`';
}

/*----------------------------------------------------------------------------*/

/**
 * Creates the FP-Guide wiki at the `target` path.
 *
 * @param {string} target The output file path.
 */
function build(target) {
  target = path.resolve(target);
  fs.writeFile(target, template.wiki(templateData), util.pitch);
}

build(_.last(process.argv));

<|edits_diff|>
--- lib/fp/build-doc.js
+++ lib/fp/build-doc.js
@@ -20,6 +20,7 @@
  * Converts arranged argument `indexes` into a named argument string
  * representation of their order.
  *
+ * @private
  * @param {number[]} indexes The arranged argument indexes.
  * @returns {string} Returns the named argument string.
  */
@@ -34,6 +35,7 @@
 /**
  * Converts `funcNames` into a chunked list string representation.
  *
+ * @private
  * @param {string[]} funcNames The function names.
  * @returns {string} Returns the function list string.
  */
<|current_version|>
    fs = require('fs-extra'),
    path = require('path');

var file = require('../common/file'),
    mapping = require('../common/mapping'),
    util = require('../common/util');

var templatePath = path.join(__dirname, 'template/doc'),
    template = file.globTemplate(path.join(templatePath, '*.jst'));

var argNames = ['a', 'b', 'c', 'd'];

var templateData = {
  'mapping': mapping,
  'toArgOrder': toArgOrder,
  'toFuncList': toFuncList
};

/**
 * Converts arranged argument `indexes` into a named argument string
 * representation of their order.
 *
 * @private
 * @param {number[]} indexes The arranged argument indexes.
 * @returns {string} Returns the named argument string.
 */
function toArgOrder(indexes) {
  var reordered = [];
  _.each(indexes, function(newIndex, index) {
    reordered[newIndex] = argNames[index];
  });
  return '`(' + reordered.join(', ') + ')`';
}

/**
 * Converts `funcNames` into a chunked list string representation.
 *
 * @private
 * @param {string[]} funcNames The function names.
 * @returns {string} Returns the function list string.
 */
function toFuncList(funcNames) {
  var chunks = _.chunk(funcNames.slice().sort(), 5),
      lastChunk = _.last(chunks),
      last = lastChunk ? lastChunk.pop() : undefined;

  chunks = _.reject(chunks, _.isEmpty);
  lastChunk = _.last(chunks);

  var result = '`' + _.map(chunks, function(chunk) {
    return chunk.join('`, `') + '`';
  }).join(',\n`');

  if (last == null) {
    return result;
  }
  if (_.size(chunks) > 1 || _.size(lastChunk) > 1) {
    result += ',';
  }
  result += ' &';
  result += _.size(lastChunk) < 5 ? ' ' : '\n';
  return result + '`' + last + '`';
}

/*----------------------------------------------------------------------------*/

/**
 * Creates the FP-Guide wiki at the `target` path.
 *
 * @param {string} target The output file path.
 */
function build(target) {
  target = path.resolve(target);
  fs.writeFile(target, template.wiki(templateData), util.pitch);
}

build(_.last(process.argv));

<|next_version|>
    fs = require('fs-extra'),
    path = require('path');

var file = require('../common/file'),
    mapping = require('../common/mapping'),
    util = require('../common/util');

var templatePath = path.join(__dirname, 'template/doc'),
    template = file.globTemplate(path.join(templatePath, '*.jst'));

var argNames = ['a', 'b', 'c', 'd'];

var templateData = {
  'mapping': mapping,
  'toArgOrder': toArgOrder,
  'toFuncList': toFuncList
};

/**
 * Converts arranged argument `indexes` into a named argument string
 * representation of their order.
 *
 * @private
 * @param {number[]} indexes The arranged argument indexes.
 * @returns {string} Returns the named argument string.
 */
function toArgOrder(indexes) {
  var reordered = [];
  _.each(indexes, function(newIndex, index) {
    reordered[newIndex] = argNames[index];
  });
  return '`(' + reordered.join(', ') + ')`';
}

/**
 * Converts `funcNames` into a chunked list string representation.
 *
 * @private
 * @param {string[]} funcNames The function names.
 * @returns {string} Returns the function list string.
 */
function toFuncList(funcNames) {
  var chunks = _.chunk(funcNames.slice().sort(), 5),
      lastChunk = _.last(chunks),
      last = lastChunk ? lastChunk.pop() : undefined;

  chunks = _.reject(chunks, _.isEmpty);
  lastChunk = _.last(chunks);

  var result = '`' + _.map(chunks, function(chunk) {
    return chunk.join('`, `') + '`';
  }).join(',\n`');

  if (last == null) {
    return result;
  }
  if (_.size(chunks) > 1 || _.size(lastChunk) > 1) {
    result += ',';
  }
  result += ' &';
  result += _.size(lastChunk) < 5 ? ' ' : '\n';
  return result + '`' + last + '`';
}

/*----------------------------------------------------------------------------*/

/**
 * Creates the FP-Guide wiki at the `target` path.
 *
 * @private
 * @param {string} target The output file path.
 */
function build(target) {
  target = path.resolve(target);
  fs.writeFile(target, template.wiki(templateData), util.pitch);
}

build(_.last(process.argv));


Update vendors.

<|original_code|>
(function() {
  var _ = typeof require == 'function' ? require('..') : window._;

  QUnit.module('Arrays');

  QUnit.test('first', function(assert) {
    assert.equal(_.first([1, 2, 3]), 1, 'can pull out the first element of an array');
    assert.equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
    assert.deepEqual(_.first([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)');
    assert.deepEqual(_.first([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)');
    assert.deepEqual(_.first([1, 2, 3], 2), [1, 2], 'can fetch the first n elements');
    assert.deepEqual(_.first([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length');
    var result = (function(){ return _.first(arguments); }(4, 3, 2, 1));
    assert.equal(result, 4, 'works on an arguments object');
    result = _.map([[1, 2, 3], [1, 2, 3]], _.first);
    assert.deepEqual(result, [1, 1], 'works well with _.map');
    assert.equal(_.first(null), void 0, 'returns undefined when called on null');
  });

  QUnit.test('head', function(assert) {
    assert.strictEqual(_.head, _.first, 'is an alias for first');
  });

  QUnit.test('take', function(assert) {
    assert.strictEqual(_.take, _.first, 'is an alias for first');
  });

  QUnit.test('rest', function(assert) {
    var numbers = [1, 2, 3, 4];
    assert.deepEqual(_.rest(numbers), [2, 3, 4], 'fetches all but the first element');
    assert.deepEqual(_.rest(numbers, 0), [1, 2, 3, 4], 'returns the whole array when index is 0');
    assert.deepEqual(_.rest(numbers, 2), [3, 4], 'returns elements starting at the given index');
    var result = (function(){ return _(arguments).rest(); }(1, 2, 3, 4));
    assert.deepEqual(result, [2, 3, 4], 'works on an arguments object');
    result = _.map([[1, 2, 3], [1, 2, 3]], _.rest);
    assert.deepEqual(_.flatten(result), [2, 3, 2, 3], 'works well with _.map');
  });

  QUnit.test('tail', function(assert) {
    assert.strictEqual(_.tail, _.rest, 'is an alias for rest');
  });

  QUnit.test('drop', function(assert) {
    assert.strictEqual(_.drop, _.rest, 'is an alias for rest');
  });

  QUnit.test('initial', function(assert) {
    assert.deepEqual(_.initial([1, 2, 3, 4, 5]), [1, 2, 3, 4], 'returns all but the last element');
    assert.deepEqual(_.initial([1, 2, 3, 4], 2), [1, 2], 'returns all but the last n elements');
    assert.deepEqual(_.initial([1, 2, 3, 4], 6), [], 'returns an empty array when n > length');
    var result = (function(){ return _(arguments).initial(); }(1, 2, 3, 4));
    assert.deepEqual(result, [1, 2, 3], 'works on an arguments object');
    result = _.map([[1, 2, 3], [1, 2, 3]], _.initial);
    assert.deepEqual(_.flatten(result), [1, 2, 1, 2], 'works well with _.map');
  });

  QUnit.test('last', function(assert) {
    assert.equal(_.last([1, 2, 3]), 3, 'can pull out the last element of an array');
    assert.equal(_([1, 2, 3]).last(), 3, 'can perform OO-style "last()"');
    assert.deepEqual(_.last([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)');
    assert.deepEqual(_.last([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)');
    assert.deepEqual(_.last([1, 2, 3], 2), [2, 3], 'can fetch the last n elements');
    assert.deepEqual(_.last([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length');
    var result = (function(){ return _(arguments).last(); }(1, 2, 3, 4));
    assert.equal(result, 4, 'works on an arguments object');
    result = _.map([[1, 2, 3], [1, 2, 3]], _.last);
    assert.deepEqual(result, [3, 3], 'works well with _.map');
    assert.equal(_.last(null), void 0, 'returns undefined when called on null');
  });

  QUnit.test('compact', function(assert) {
    assert.deepEqual(_.compact([1, false, null, 0, '', void 0, NaN, 2]), [1, 2], 'removes all falsy values');
    var result = (function(){ return _.compact(arguments); }(0, 1, false, 2, false, 3));
    assert.deepEqual(result, [1, 2, 3], 'works on an arguments object');
    result = _.map([[1, false, false], [false, false, 3]], _.compact);
    assert.deepEqual(result, [[1], [3]], 'works well with _.map');
  });

  QUnit.test('flatten', function(assert) {
    assert.deepEqual(_.flatten(null), [], 'supports null');
    assert.deepEqual(_.flatten(void 0), [], 'supports undefined');

    assert.deepEqual(_.flatten([[], [[]], []]), [], 'supports empty arrays');
    assert.deepEqual(_.flatten([[], [[]], []], true), [[]], 'can shallowly flatten empty arrays');

    var list = [1, [2], [3, [[[4]]]]];
    assert.deepEqual(_.flatten(list), [1, 2, 3, 4], 'can flatten nested arrays');
    assert.deepEqual(_.flatten(list, true), [1, 2, 3, [[[4]]]], 'can shallowly flatten nested arrays');
    var result = (function(){ return _.flatten(arguments); }(1, [2], [3, [[[4]]]]));
    assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
    list = [[1], [2], [3], [[4]]];
    assert.deepEqual(_.flatten(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays');
<|edits_diff|>
--- vendor/underscore/test/arrays.js
+++ vendor/underscore/test/arrays.js
@@ -15,6 +15,10 @@
     result = _.map([[1, 2, 3], [1, 2, 3]], _.first);
     assert.deepEqual(result, [1, 1], 'works well with _.map');
     assert.equal(_.first(null), void 0, 'returns undefined when called on null');
+
+    Array.prototype[0] = 'boo';
+    assert.equal(_.first([]), void 0, 'return undefined when called on a empty array');
+    delete Array.prototype[0];
   });

   QUnit.test('head', function(assert) {
<|current_version|>
(function() {
  var _ = typeof require == 'function' ? require('..') : window._;

  QUnit.module('Arrays');

  QUnit.test('first', function(assert) {
    assert.equal(_.first([1, 2, 3]), 1, 'can pull out the first element of an array');
    assert.equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
    assert.deepEqual(_.first([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)');
    assert.deepEqual(_.first([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)');
    assert.deepEqual(_.first([1, 2, 3], 2), [1, 2], 'can fetch the first n elements');
    assert.deepEqual(_.first([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length');
    var result = (function(){ return _.first(arguments); }(4, 3, 2, 1));
    assert.equal(result, 4, 'works on an arguments object');
    result = _.map([[1, 2, 3], [1, 2, 3]], _.first);
    assert.deepEqual(result, [1, 1], 'works well with _.map');
    assert.equal(_.first(null), void 0, 'returns undefined when called on null');

    Array.prototype[0] = 'boo';
    assert.equal(_.first([]), void 0, 'return undefined when called on a empty array');
    delete Array.prototype[0];
  });

  QUnit.test('head', function(assert) {
    assert.strictEqual(_.head, _.first, 'is an alias for first');
  });

  QUnit.test('take', function(assert) {
    assert.strictEqual(_.take, _.first, 'is an alias for first');
  });

  QUnit.test('rest', function(assert) {
    var numbers = [1, 2, 3, 4];
    assert.deepEqual(_.rest(numbers), [2, 3, 4], 'fetches all but the first element');
    assert.deepEqual(_.rest(numbers, 0), [1, 2, 3, 4], 'returns the whole array when index is 0');
    assert.deepEqual(_.rest(numbers, 2), [3, 4], 'returns elements starting at the given index');
    var result = (function(){ return _(arguments).rest(); }(1, 2, 3, 4));
    assert.deepEqual(result, [2, 3, 4], 'works on an arguments object');
    result = _.map([[1, 2, 3], [1, 2, 3]], _.rest);
    assert.deepEqual(_.flatten(result), [2, 3, 2, 3], 'works well with _.map');
  });

  QUnit.test('tail', function(assert) {
    assert.strictEqual(_.tail, _.rest, 'is an alias for rest');
  });

  QUnit.test('drop', function(assert) {
    assert.strictEqual(_.drop, _.rest, 'is an alias for rest');
  });

  QUnit.test('initial', function(assert) {
    assert.deepEqual(_.initial([1, 2, 3, 4, 5]), [1, 2, 3, 4], 'returns all but the last element');
    assert.deepEqual(_.initial([1, 2, 3, 4], 2), [1, 2], 'returns all but the last n elements');
    assert.deepEqual(_.initial([1, 2, 3, 4], 6), [], 'returns an empty array when n > length');
    var result = (function(){ return _(arguments).initial(); }(1, 2, 3, 4));
    assert.deepEqual(result, [1, 2, 3], 'works on an arguments object');
    result = _.map([[1, 2, 3], [1, 2, 3]], _.initial);
    assert.deepEqual(_.flatten(result), [1, 2, 1, 2], 'works well with _.map');
  });

  QUnit.test('last', function(assert) {
    assert.equal(_.last([1, 2, 3]), 3, 'can pull out the last element of an array');
    assert.equal(_([1, 2, 3]).last(), 3, 'can perform OO-style "last()"');
    assert.deepEqual(_.last([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)');
    assert.deepEqual(_.last([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)');
    assert.deepEqual(_.last([1, 2, 3], 2), [2, 3], 'can fetch the last n elements');
    assert.deepEqual(_.last([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length');
    var result = (function(){ return _(arguments).last(); }(1, 2, 3, 4));
    assert.equal(result, 4, 'works on an arguments object');
    result = _.map([[1, 2, 3], [1, 2, 3]], _.last);
    assert.deepEqual(result, [3, 3], 'works well with _.map');
    assert.equal(_.last(null), void 0, 'returns undefined when called on null');
  });

  QUnit.test('compact', function(assert) {
    assert.deepEqual(_.compact([1, false, null, 0, '', void 0, NaN, 2]), [1, 2], 'removes all falsy values');
    var result = (function(){ return _.compact(arguments); }(0, 1, false, 2, false, 3));
    assert.deepEqual(result, [1, 2, 3], 'works on an arguments object');
    result = _.map([[1, false, false], [false, false, 3]], _.compact);
    assert.deepEqual(result, [[1], [3]], 'works well with _.map');
  });

  QUnit.test('flatten', function(assert) {
    assert.deepEqual(_.flatten(null), [], 'supports null');
    assert.deepEqual(_.flatten(void 0), [], 'supports undefined');

    assert.deepEqual(_.flatten([[], [[]], []]), [], 'supports empty arrays');
    assert.deepEqual(_.flatten([[], [[]], []], true), [[]], 'can shallowly flatten empty arrays');

    var list = [1, [2], [3, [[[4]]]]];
    assert.deepEqual(_.flatten(list), [1, 2, 3, 4], 'can flatten nested arrays');
    assert.deepEqual(_.flatten(list, true), [1, 2, 3, [[[4]]]], 'can shallowly flatten nested arrays');
    var result = (function(){ return _.flatten(arguments); }(1, [2], [3, [[[4]]]]));
    assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
    list = [[1], [2], [3], [[4]]];
    assert.deepEqual(_.flatten(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays');
<|next_version|>
(function() {
  var _ = typeof require == 'function' ? require('..') : window._;

  QUnit.module('Arrays');

  QUnit.test('first', function(assert) {
    assert.equal(_.first([1, 2, 3]), 1, 'can pull out the first element of an array');
    assert.equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
    assert.deepEqual(_.first([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)');
    assert.deepEqual(_.first([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)');
    assert.deepEqual(_.first([1, 2, 3], 2), [1, 2], 'can fetch the first n elements');
    assert.deepEqual(_.first([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length');
    var result = (function(){ return _.first(arguments); }(4, 3, 2, 1));
    assert.equal(result, 4, 'works on an arguments object');
    result = _.map([[1, 2, 3], [1, 2, 3]], _.first);
    assert.deepEqual(result, [1, 1], 'works well with _.map');
    assert.equal(_.first(null), void 0, 'returns undefined when called on null');

    Array.prototype[0] = 'boo';
    assert.equal(_.first([]), void 0, 'return undefined when called on a empty array');
    delete Array.prototype[0];
  });

  QUnit.test('head', function(assert) {
    assert.strictEqual(_.head, _.first, 'is an alias for first');
  });

  QUnit.test('take', function(assert) {
    assert.strictEqual(_.take, _.first, 'is an alias for first');
  });

  QUnit.test('rest', function(assert) {
    var numbers = [1, 2, 3, 4];
    assert.deepEqual(_.rest(numbers), [2, 3, 4], 'fetches all but the first element');
    assert.deepEqual(_.rest(numbers, 0), [1, 2, 3, 4], 'returns the whole array when index is 0');
    assert.deepEqual(_.rest(numbers, 2), [3, 4], 'returns elements starting at the given index');
    var result = (function(){ return _(arguments).rest(); }(1, 2, 3, 4));
    assert.deepEqual(result, [2, 3, 4], 'works on an arguments object');
    result = _.map([[1, 2, 3], [1, 2, 3]], _.rest);
    assert.deepEqual(_.flatten(result), [2, 3, 2, 3], 'works well with _.map');
  });

  QUnit.test('tail', function(assert) {
    assert.strictEqual(_.tail, _.rest, 'is an alias for rest');
  });

  QUnit.test('drop', function(assert) {
    assert.strictEqual(_.drop, _.rest, 'is an alias for rest');
  });

  QUnit.test('initial', function(assert) {
    assert.deepEqual(_.initial([1, 2, 3, 4, 5]), [1, 2, 3, 4], 'returns all but the last element');
    assert.deepEqual(_.initial([1, 2, 3, 4], 2), [1, 2], 'returns all but the last n elements');
    assert.deepEqual(_.initial([1, 2, 3, 4], 6), [], 'returns an empty array when n > length');
    var result = (function(){ return _(arguments).initial(); }(1, 2, 3, 4));
    assert.deepEqual(result, [1, 2, 3], 'works on an arguments object');
    result = _.map([[1, 2, 3], [1, 2, 3]], _.initial);
    assert.deepEqual(_.flatten(result), [1, 2, 1, 2], 'works well with _.map');
  });

  QUnit.test('last', function(assert) {
    assert.equal(_.last([1, 2, 3]), 3, 'can pull out the last element of an array');
    assert.equal(_([1, 2, 3]).last(), 3, 'can perform OO-style "last()"');
    assert.deepEqual(_.last([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)');
    assert.deepEqual(_.last([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)');
    assert.deepEqual(_.last([1, 2, 3], 2), [2, 3], 'can fetch the last n elements');
    assert.deepEqual(_.last([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length');
    var result = (function(){ return _(arguments).last(); }(1, 2, 3, 4));
    assert.equal(result, 4, 'works on an arguments object');
    result = _.map([[1, 2, 3], [1, 2, 3]], _.last);
    assert.deepEqual(result, [3, 3], 'works well with _.map');
    assert.equal(_.last(null), void 0, 'returns undefined when called on null');

    var arr = [];
    arr[-1] = 'boo';
    assert.equal(_.last(arr), void 0, 'return undefined when called on a empty array');
  });

  QUnit.test('compact', function(assert) {
    assert.deepEqual(_.compact([1, false, null, 0, '', void 0, NaN, 2]), [1, 2], 'removes all falsy values');
    var result = (function(){ return _.compact(arguments); }(0, 1, false, 2, false, 3));
    assert.deepEqual(result, [1, 2, 3], 'works on an arguments object');
    result = _.map([[1, false, false], [false, false, 3]], _.compact);
    assert.deepEqual(result, [[1], [3]], 'works well with _.map');
  });

  QUnit.test('flatten', function(assert) {
    assert.deepEqual(_.flatten(null), [], 'supports null');
    assert.deepEqual(_.flatten(void 0), [], 'supports undefined');

    assert.deepEqual(_.flatten([[], [[]], []]), [], 'supports empty arrays');
    assert.deepEqual(_.flatten([[], [[]], []], true), [[]], 'can shallowly flatten empty arrays');

    var list = [1, [2], [3, [[[4]]]]];
    assert.deepEqual(_.flatten(list), [1, 2, 3, 4], 'can flatten nested arrays');
    assert.deepEqual(_.flatten(list, true), [1, 2, 3, [[[4]]]], 'can shallowly flatten nested arrays');
    var result = (function(){ return _.flatten(arguments); }(1, [2], [3, [[[4]]]]));
    assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
    list = [[1], [2], [3], [[4]]];
    assert.deepEqual(_.flatten(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays');


Add bizarro Promise test.

<|original_code|>
              name = caller ? caller.name : '';

          if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) {
            return Buffer;
          }
        }
      });
    }
    if (Map) {
      setProperty(root, 'Map', (function() {
        var count = 0;
        return function() {
          if (count++) {
            return new Map;
          }
          setProperty(root, 'Map', Map);
          return {};
        };
      }()));

      setProperty(root.Map, 'toString', createToString('Map'));
    }
    setProperty(root, 'Set', noop);
    setProperty(root, 'Symbol', undefined);
    setProperty(root, 'WeakMap', noop);

    // Fake `WinRTError`.
    setProperty(root, 'WinRTError', Error);

    // Clear cache so lodash can be reloaded.
    emptyObject(require.cache);

    // Load lodash and expose it to the bad extensions/shims.
    lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['default'] || lodashBizarro;
    root._ = oldDash;

    // Restore built-in methods.
    setProperty(Object, 'create', create);
    setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);
    setProperty(root, 'Buffer', Buffer);

    if (getSymbols) {
      Object.getOwnPropertySymbols = getSymbols;
    } else {
      delete Object.getOwnPropertySymbols;
    }
    if (Map) {
      setProperty(root, 'Map', Map);
    } else {
      delete root.Map;
    }
    if (Set) {
      setProperty(root, 'Set', Set);
    } else {
      delete root.Set;
    }
    if (Symbol) {
      setProperty(root, 'Symbol', Symbol);
    } else {
      delete root.Symbol;
    }
    if (WeakMap) {
      setProperty(root, 'WeakMap', WeakMap);
    } else {
      delete root.WeakMap;
    }
    delete root.WinRTError;
    delete funcProto._method;
  }());

  // Add other realm values from the `vm` module.
  lodashStable.attempt(function() {
    lodashStable.assign(realm, require('vm').runInNewContext([
      '(function() {',
<|edits_diff|>
--- test/test.js
+++ test/test.js
@@ -20,6 +20,7 @@

       setProperty(root.Map, 'toString', createToString('Map'));
     }
+    setProperty(root, 'Promise', noop);
     setProperty(root, 'Set', noop);
     setProperty(root, 'Symbol', undefined);
     setProperty(root, 'WeakMap', noop);
<|current_version|>
              name = caller ? caller.name : '';

          if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) {
            return Buffer;
          }
        }
      });
    }
    if (Map) {
      setProperty(root, 'Map', (function() {
        var count = 0;
        return function() {
          if (count++) {
            return new Map;
          }
          setProperty(root, 'Map', Map);
          return {};
        };
      }()));

      setProperty(root.Map, 'toString', createToString('Map'));
    }
    setProperty(root, 'Promise', noop);
    setProperty(root, 'Set', noop);
    setProperty(root, 'Symbol', undefined);
    setProperty(root, 'WeakMap', noop);

    // Fake `WinRTError`.
    setProperty(root, 'WinRTError', Error);

    // Clear cache so lodash can be reloaded.
    emptyObject(require.cache);

    // Load lodash and expose it to the bad extensions/shims.
    lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['default'] || lodashBizarro;
    root._ = oldDash;

    // Restore built-in methods.
    setProperty(Object, 'create', create);
    setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);
    setProperty(root, 'Buffer', Buffer);

    if (getSymbols) {
      Object.getOwnPropertySymbols = getSymbols;
    } else {
      delete Object.getOwnPropertySymbols;
    }
    if (Map) {
      setProperty(root, 'Map', Map);
    } else {
      delete root.Map;
    }
    if (Set) {
      setProperty(root, 'Set', Set);
    } else {
      delete root.Set;
    }
    if (Symbol) {
      setProperty(root, 'Symbol', Symbol);
    } else {
      delete root.Symbol;
    }
    if (WeakMap) {
      setProperty(root, 'WeakMap', WeakMap);
    } else {
      delete root.WeakMap;
    }
    delete root.WinRTError;
    delete funcProto._method;
  }());

  // Add other realm values from the `vm` module.
  lodashStable.attempt(function() {
    lodashStable.assign(realm, require('vm').runInNewContext([
      '(function() {',
<|next_version|>
              name = caller ? caller.name : '';

          if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) {
            return Buffer;
          }
        }
      });
    }
    if (Map) {
      setProperty(root, 'Map', (function() {
        var count = 0;
        return function() {
          if (count++) {
            return new Map;
          }
          setProperty(root, 'Map', Map);
          return {};
        };
      }()));

      setProperty(root.Map, 'toString', createToString('Map'));
    }
    setProperty(root, 'Promise', noop);
    setProperty(root, 'Set', noop);
    setProperty(root, 'Symbol', undefined);
    setProperty(root, 'WeakMap', noop);

    // Fake `WinRTError`.
    setProperty(root, 'WinRTError', Error);

    // Clear cache so lodash can be reloaded.
    emptyObject(require.cache);

    // Load lodash and expose it to the bad extensions/shims.
    lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['default'] || lodashBizarro;
    root._ = oldDash;

    // Restore built-in methods.
    setProperty(Object, 'create', create);
    setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);
    setProperty(root, 'Buffer', Buffer);

    if (getSymbols) {
      Object.getOwnPropertySymbols = getSymbols;
    } else {
      delete Object.getOwnPropertySymbols;
    }
    if (Map) {
      setProperty(root, 'Map', Map);
    } else {
      delete root.Map;
    }
    if (Promise) {
      setProperty(root, 'Promise', Promise);
    } else {
      delete root.Promise;
    }
    if (Set) {
      setProperty(root, 'Set', Set);
    } else {
      delete root.Set;
    }
    if (Symbol) {
      setProperty(root, 'Symbol', Symbol);
    } else {
      delete root.Symbol;
    }
    if (WeakMap) {
      setProperty(root, 'WeakMap', WeakMap);
    } else {
      delete root.WeakMap;
    }
    delete root.WinRTError;
    delete funcProto._method;
  }());

  // Add other realm values from the `vm` module.
  lodashStable.attempt(function() {
    lodashStable.assign(realm, require('vm').runInNewContext([
      '(function() {',


fp docs - Remove notes about mutation in description.

<|original_code|>
var Entry = require('docdown/lib/entry'),
    getReorderedParams = require('./parameters'),
    getReorderedExample = require('./example');

/**
 * Updates `docdown` `Entry`'s prototype so that parameters/arguments are reordered according to `mapping`.
 */
module.exports = function applyFPMapping(mapping) {
  Entry.prototype.getParams = getReorderedParams(mapping);
  Entry.prototype.getExample = getReorderedExample(mapping);
};

<|edits_diff|>
--- lib/doc/apply-fp-mapping/index.js
+++ lib/doc/apply-fp-mapping/index.js
@@ -1,4 +1,5 @@
 var Entry = require('docdown/lib/entry'),
+    getUpdatedDesc = require('./description'),
     getReorderedParams = require('./parameters'),
     getReorderedExample = require('./example');

<|current_version|>
var Entry = require('docdown/lib/entry'),
    getUpdatedDesc = require('./description'),
    getReorderedParams = require('./parameters'),
    getReorderedExample = require('./example');

/**
 * Updates `docdown` `Entry`'s prototype so that parameters/arguments are reordered according to `mapping`.
 */
module.exports = function applyFPMapping(mapping) {
  Entry.prototype.getParams = getReorderedParams(mapping);
  Entry.prototype.getExample = getReorderedExample(mapping);
};

<|next_version|>
var Entry = require('docdown/lib/entry'),
    getUpdatedDesc = require('./description'),
    getReorderedParams = require('./parameters'),
    getReorderedExample = require('./example');

/**
 * Updates `docdown` `Entry`'s prototype so that parameters/arguments are reordered according to `mapping`.
 */
module.exports = function applyFPMapping(mapping) {
  Entry.prototype.getDesc = getUpdatedDesc;
  Entry.prototype.getParams = getReorderedParams(mapping);
  Entry.prototype.getExample = getReorderedExample(mapping);
};


Add bizarro `Map`.

<|original_code|>

    function createToString(funcName) {
      return _.constant(nativeString.replace(reToString, funcName));
    }

    // Allow bypassing native checks.
    setProperty(funcProto, 'toString', function wrapper() {
      setProperty(funcProto, 'toString', fnToString);
      var result = _.has(this, 'toString') ? this.toString() : fnToString.call(this);
      setProperty(funcProto, 'toString', wrapper);
      return result;
    });

    // Add prototype extensions.
    funcProto._method = _.noop;

    // Set bad shims.
    var _propertyIsEnumerable = objectProto.propertyIsEnumerable;
    setProperty(objectProto, 'propertyIsEnumerable', function(key) {
      return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
    });

    var _Set = root.Set;
    setProperty(root, 'Set', _.noop);

    var _WeakMap = root.WeakMap;
    setProperty(root, 'WeakMap', _.noop);

    // Fake `WinRTError`.
    setProperty(root, 'WinRTError', Error);

    // Clear cache so lodash can be reloaded.
    emptyObject(require.cache);

    // Load lodash and expose it to the bad extensions/shims.
    lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['default'] || lodashBizarro;
    root._ = oldDash;

    // Restore built-in methods.
    setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);

    if (_Set) {
      setProperty(root, 'Set', Set);
    } else {
      delete root.Set;
    }
    if (_WeakMap) {
      setProperty(root, 'WeakMap', WeakMap);
    } else {
      delete root.WeakMap;
    }
    delete root.WinRTError;
    delete funcProto._method;
  }());

  // Add other realm values from the `vm` module.
  _.attempt(function() {
    _.extend(realm, require('vm').runInNewContext([
      '(function() {',
      '  var root = this;',
      '',
      '  var object = {',
      "    'arguments': (function() { return arguments; }(1, 2, 3)),",
      "    'array': [1, 2, 3],",
      "    'arrayBuffer': new (this.ArrayByffer || Object),",
<|edits_diff|>
--- test/test.js
+++ test/test.js
@@ -19,6 +19,9 @@
     setProperty(objectProto, 'propertyIsEnumerable', function(key) {
       return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
     });
+
+    var _Map = root.Map;
+    setProperty(root, 'Map', _.noop);

     var _Set = root.Set;
     setProperty(root, 'Set', _.noop);
<|current_version|>

    function createToString(funcName) {
      return _.constant(nativeString.replace(reToString, funcName));
    }

    // Allow bypassing native checks.
    setProperty(funcProto, 'toString', function wrapper() {
      setProperty(funcProto, 'toString', fnToString);
      var result = _.has(this, 'toString') ? this.toString() : fnToString.call(this);
      setProperty(funcProto, 'toString', wrapper);
      return result;
    });

    // Add prototype extensions.
    funcProto._method = _.noop;

    // Set bad shims.
    var _propertyIsEnumerable = objectProto.propertyIsEnumerable;
    setProperty(objectProto, 'propertyIsEnumerable', function(key) {
      return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
    });

    var _Map = root.Map;
    setProperty(root, 'Map', _.noop);

    var _Set = root.Set;
    setProperty(root, 'Set', _.noop);

    var _WeakMap = root.WeakMap;
    setProperty(root, 'WeakMap', _.noop);

    // Fake `WinRTError`.
    setProperty(root, 'WinRTError', Error);

    // Clear cache so lodash can be reloaded.
    emptyObject(require.cache);

    // Load lodash and expose it to the bad extensions/shims.
    lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['default'] || lodashBizarro;
    root._ = oldDash;

    // Restore built-in methods.
    setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);

    if (_Set) {
      setProperty(root, 'Set', Set);
    } else {
      delete root.Set;
    }
    if (_WeakMap) {
      setProperty(root, 'WeakMap', WeakMap);
    } else {
      delete root.WeakMap;
    }
    delete root.WinRTError;
    delete funcProto._method;
  }());

  // Add other realm values from the `vm` module.
  _.attempt(function() {
    _.extend(realm, require('vm').runInNewContext([
      '(function() {',
      '  var root = this;',
      '',
      '  var object = {',
      "    'arguments': (function() { return arguments; }(1, 2, 3)),",
      "    'array': [1, 2, 3],",
      "    'arrayBuffer': new (this.ArrayByffer || Object),",
<|next_version|>

    function createToString(funcName) {
      return _.constant(nativeString.replace(reToString, funcName));
    }

    // Allow bypassing native checks.
    setProperty(funcProto, 'toString', function wrapper() {
      setProperty(funcProto, 'toString', fnToString);
      var result = _.has(this, 'toString') ? this.toString() : fnToString.call(this);
      setProperty(funcProto, 'toString', wrapper);
      return result;
    });

    // Add prototype extensions.
    funcProto._method = _.noop;

    // Set bad shims.
    var _propertyIsEnumerable = objectProto.propertyIsEnumerable;
    setProperty(objectProto, 'propertyIsEnumerable', function(key) {
      return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
    });

    var _Map = root.Map;
    setProperty(root, 'Map', _.noop);

    var _Set = root.Set;
    setProperty(root, 'Set', _.noop);

    var _WeakMap = root.WeakMap;
    setProperty(root, 'WeakMap', _.noop);

    // Fake `WinRTError`.
    setProperty(root, 'WinRTError', Error);

    // Clear cache so lodash can be reloaded.
    emptyObject(require.cache);

    // Load lodash and expose it to the bad extensions/shims.
    lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['default'] || lodashBizarro;
    root._ = oldDash;

    // Restore built-in methods.
    setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);

    if (_Map) {
      setProperty(root, 'Map', Map);
    } else {
      delete root.Map;
    }
    if (_Set) {
      setProperty(root, 'Set', Set);
    } else {
      delete root.Set;
    }
    if (_WeakMap) {
      setProperty(root, 'WeakMap', WeakMap);
    } else {
      delete root.WeakMap;
    }
    delete root.WinRTError;
    delete funcProto._method;
  }());

  // Add other realm values from the `vm` module.
  _.attempt(function() {
    _.extend(realm, require('vm').runInNewContext([
      '(function() {',
      '  var root = this;',
      '',
      '  var object = {',
      "    'arguments': (function() { return arguments; }(1, 2, 3)),",
      "    'array': [1, 2, 3],",
      "    'arrayBuffer': new (this.ArrayByffer || Object),",


Make `baseSortedIndex` handle `NaN` correctly when comparing numbers.

<|original_code|>
      });
      return !!result;
    }

    /**
     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` without
     * support for callback shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {*} value The value to evaluate.
     * @param {Function} iterator The function called per iteration.
     * @param {boolean} [retHighest=false] Specify returning the highest, instead
     *  of the lowest, index at which a value should be inserted into `array`.
     * @returns {number} Returns the index at which `value` should be inserted
     *  into `array`.
     */
    function baseSortedIndex(array, value, iterator, retHighest) {
      var low = 0,
          high = array ? array.length : low;

      value = iterator(value);
      while (low < high) {
        var mid = (low + high) >>> 1,
            computed = iterator(array[mid]);

        if (retHighest ? computed <= value : computed < value) {
          low = mid + 1;
        } else {
          high = mid;
        }
      }
      return high;
    }

    /**
     * The base implementation of `_.uniq` without support for callback shorthands
     * and `this` binding.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {Function} [iterator] The function called per iteration.
     * @returns {Array} Returns the new duplicate-value-free array.
     */
    function baseUniq(array, iterator) {
      var index = -1,
          indexOf = getIndexOf(),
          length = array.length,
          prereq = indexOf == baseIndexOf,
          isLarge = prereq && createCache && length >= 200,
<|edits_diff|>
--- lodash.js
+++ lodash.js
@@ -20,6 +20,9 @@
           high = array ? array.length : low;

       value = iterator(value);
+      var hintNum = typeof value == 'number' ||
+        (value != null && isFunction(value.valueOf) && typeof value.valueOf() == 'number');
+
       while (low < high) {
         var mid = (low + high) >>> 1,
             computed = iterator(array[mid]);
<|current_version|>
      });
      return !!result;
    }

    /**
     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` without
     * support for callback shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {*} value The value to evaluate.
     * @param {Function} iterator The function called per iteration.
     * @param {boolean} [retHighest=false] Specify returning the highest, instead
     *  of the lowest, index at which a value should be inserted into `array`.
     * @returns {number} Returns the index at which `value` should be inserted
     *  into `array`.
     */
    function baseSortedIndex(array, value, iterator, retHighest) {
      var low = 0,
          high = array ? array.length : low;

      value = iterator(value);
      var hintNum = typeof value == 'number' ||
        (value != null && isFunction(value.valueOf) && typeof value.valueOf() == 'number');

      while (low < high) {
        var mid = (low + high) >>> 1,
            computed = iterator(array[mid]);

        if (retHighest ? computed <= value : computed < value) {
          low = mid + 1;
        } else {
          high = mid;
        }
      }
      return high;
    }

    /**
     * The base implementation of `_.uniq` without support for callback shorthands
     * and `this` binding.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {Function} [iterator] The function called per iteration.
     * @returns {Array} Returns the new duplicate-value-free array.
     */
    function baseUniq(array, iterator) {
      var index = -1,
          indexOf = getIndexOf(),
          length = array.length,
          prereq = indexOf == baseIndexOf,
          isLarge = prereq && createCache && length >= 200,
<|next_version|>
      });
      return !!result;
    }

    /**
     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` without
     * support for callback shorthands and `this` binding.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {*} value The value to evaluate.
     * @param {Function} iterator The function called per iteration.
     * @param {boolean} [retHighest=false] Specify returning the highest, instead
     *  of the lowest, index at which a value should be inserted into `array`.
     * @returns {number} Returns the index at which `value` should be inserted
     *  into `array`.
     */
    function baseSortedIndex(array, value, iterator, retHighest) {
      var low = 0,
          high = array ? array.length : low;

      value = iterator(value);
      var hintNum = typeof value == 'number' ||
        (value != null && isFunction(value.valueOf) && typeof value.valueOf() == 'number');

      while (low < high) {
        var mid = (low + high) >>> 1,
            computed = iterator(array[mid]);

        if (hintNum && typeof computed != 'undefined') {
          computed = +computed || 0;
        }
        if (retHighest ? computed <= value : computed < value) {
          low = mid + 1;
        } else {
          high = mid;
        }
      }
      return high;
    }

    /**
     * The base implementation of `_.uniq` without support for callback shorthands
     * and `this` binding.
     *
     * @private
     * @param {Array} array The array to inspect.
     * @param {Function} [iterator] The function called per iteration.
     * @returns {Array} Returns the new duplicate-value-free array.
     */
    function baseUniq(array, iterator) {
      var index = -1,
          indexOf = getIndexOf(),
          length = array.length,
          prereq = indexOf == baseIndexOf,
          isLarge = prereq && createCache && length >= 200,


Update Backbone tests to 1.1.1.

<|original_code|>
(function() {

  var sync = Backbone.sync;
  var ajax = Backbone.ajax;
  var emulateHTTP = Backbone.emulateHTTP;
  var emulateJSON = Backbone.emulateJSON;

  QUnit.testStart(function() {
    var env = this.config.current.testEnvironment;

    // Capture ajax settings for comparison.
    Backbone.ajax = function(settings) {
      env.ajaxSettings = settings;
    };

    // Capture the arguments to Backbone.sync for comparison.
    Backbone.sync = function(method, model, options) {
      env.syncArgs = {
        method: method,
        model: model,
        options: options
      };
      sync.apply(this, arguments);
    };

  });

  QUnit.testDone(function() {
    Backbone.sync = sync;
    Backbone.ajax = ajax;
    Backbone.emulateHTTP = emulateHTTP;
    Backbone.emulateJSON = emulateJSON;
  });

})();

<|edits_diff|>
--- vendor/backbone/test/environment.js
+++ vendor/backbone/test/environment.js
@@ -4,9 +4,15 @@
   var ajax = Backbone.ajax;
   var emulateHTTP = Backbone.emulateHTTP;
   var emulateJSON = Backbone.emulateJSON;
+  var history = window.history;
+  var pushState = history.pushState;
+  var replaceState = history.replaceState;

   QUnit.testStart(function() {
     var env = this.config.current.testEnvironment;
+
+    // We never want to actually call these during tests.
+    history.pushState = history.replaceState = function(){};

     // Capture ajax settings for comparison.
     Backbone.ajax = function(settings) {
<|current_version|>
(function() {

  var sync = Backbone.sync;
  var ajax = Backbone.ajax;
  var emulateHTTP = Backbone.emulateHTTP;
  var emulateJSON = Backbone.emulateJSON;
  var history = window.history;
  var pushState = history.pushState;
  var replaceState = history.replaceState;

  QUnit.testStart(function() {
    var env = this.config.current.testEnvironment;

    // We never want to actually call these during tests.
    history.pushState = history.replaceState = function(){};

    // Capture ajax settings for comparison.
    Backbone.ajax = function(settings) {
      env.ajaxSettings = settings;
    };

    // Capture the arguments to Backbone.sync for comparison.
    Backbone.sync = function(method, model, options) {
      env.syncArgs = {
        method: method,
        model: model,
        options: options
      };
      sync.apply(this, arguments);
    };

  });

  QUnit.testDone(function() {
    Backbone.sync = sync;
    Backbone.ajax = ajax;
    Backbone.emulateHTTP = emulateHTTP;
    Backbone.emulateJSON = emulateJSON;
  });

})();

<|next_version|>
(function() {

  var sync = Backbone.sync;
  var ajax = Backbone.ajax;
  var emulateHTTP = Backbone.emulateHTTP;
  var emulateJSON = Backbone.emulateJSON;
  var history = window.history;
  var pushState = history.pushState;
  var replaceState = history.replaceState;

  QUnit.testStart(function() {
    var env = this.config.current.testEnvironment;

    // We never want to actually call these during tests.
    history.pushState = history.replaceState = function(){};

    // Capture ajax settings for comparison.
    Backbone.ajax = function(settings) {
      env.ajaxSettings = settings;
    };

    // Capture the arguments to Backbone.sync for comparison.
    Backbone.sync = function(method, model, options) {
      env.syncArgs = {
        method: method,
        model: model,
        options: options
      };
      sync.apply(this, arguments);
    };

  });

  QUnit.testDone(function() {
    Backbone.sync = sync;
    Backbone.ajax = ajax;
    Backbone.emulateHTTP = emulateHTTP;
    Backbone.emulateJSON = emulateJSON;
    history.pushState = pushState;
    history.replaceState = replaceState;
  });

})();