<commit_before>var http = require('http');

var tasks, numberOfTasks;

process.stdin.resume();
process.stdin.setEncoding('utf8');

process.stdin.on('data', function(input) {
  tasks = input.split("\n").filter(function(n){return n});
  console.log(tasks + "\n");
  numberOfTasks = tasks.length;
});

var counter = 0;

process.stdin.on('end', function() {
  console.log("Finish reading data\n");
  process.stdin.pause();

  var exit_status = 0;

  var server = http.createServer()
  server.listen(1337, 'localhost');
  server.setTimeout(50);

  server.on("request", function (req, res) {
    console.log(req.url);

    switch(req.url) {

      case '/scenario':
        incrementCounterAndRespond(res, tasks.shift() );
        break;

      case '/passed':
        analysePostData(req);
        incrementCounterAndRespond(res, "Ok");
        break;

      case '/failed':
        analysePostData(req);
        exit_status = 1;
        incrementCounterAndRespond(res, "Aww");
        break;

      default:
        res.end();
        break;
    }

    killProcessWhenAllFinish(server, exit_status);
  });

  console.log('Server running at http://127.0.0.1:1337/');

  });

var qs = require('querystring');
function analysePostData (request) {
   var data = '';
   request.on("data", function(input) {
     data += input;
   });

   request.on("end", function() {
     var params = qs.parse(data);
     recordResult( params['task'] , params['output'] );
   });
}

var failedResults = {};
function recordResult (taskDesc, output ) {
  failedResults[ taskDesc ] = output;
}

function incrementCounterAndRespond(res, responseText) {
  counter++;
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end(responseText);
}

function killProcessWhenAllFinish(server, exit_status) {
  if( counter > numberOfTasks*2 ) {
    outputFailedTasks();
    outputStatistic();
    server.close( function () {
      process.exit(exit_status);
    });
  }
}

function outputFailedTasks() {
  for( var taskDesc in failedResults) {
    console.log( failedResults[taskDesc] + "\n" );
  }
}

function outputStatistic() {
  var failedTasks = Object.keys(failedResults).length
  var passedTasks = numberOfTasks - failedTasks;
  console.log( "*************************************" );
  console.log( "Total tasks ran: " + numberOfTasks );
  console.log( passedTasks + " Passed" );
  console.log( failedTasks + " Failed" );
  console.log( "*************************************" );
}
<commit_msg>cleanup<commit_after>var http = require('http');

var tasks, numberOfTasks;

process.stdin.resume();
process.stdin.setEncoding('utf8');

process.stdin.on('data', function(input) {
  tasks = input.split("\n").filter(function(n){return n});
  numberOfTasks = tasks.length;
});

var counter = 0;

process.stdin.on('end', function() {
  console.log("Finish reading all the task to run\n");
  process.stdin.pause();

  var exit_status = 0;

  var server = http.createServer()
  server.listen(1337, 'localhost');
  server.setTimeout(50);

  server.on("request", function (req, res) {

    switch(req.url) {

      case '/scenario':
        incrementCounterAndRespond(res, tasks.shift() );
        break;

      case '/passed':
        analysePostData(req);
        incrementCounterAndRespond(res, "Ok");
        break;

      case '/failed':
        analysePostData(req);
        exit_status = 1;
        incrementCounterAndRespond(res, "Aww");
        break;

      default:
        res.end();
        break;
    }

    killProcessWhenAllFinish(server, exit_status);
  });

  console.log('Server running at http://127.0.0.1:1337/');

  });

var qs = require('querystring');
function analysePostData (request) {
   var data = '';
   request.on("data", function(input) {
     data += input;
   });

   request.on("end", function() {
     var params = qs.parse(data);
     recordResult( params['task'] , params['output'] );
   });
}

var failedResults = {};
function recordResult (taskDesc, output ) {
  failedResults[ taskDesc ] = output;
}

function incrementCounterAndRespond(res, responseText) {
  counter++;
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end(responseText);
}

function killProcessWhenAllFinish(server, exit_status) {
  if( counter > numberOfTasks*2 ) {
    outputFailedTasks();
    outputStatistic();
    server.close( function () {
      process.exit(exit_status);
    });
  }
}

function outputFailedTasks() {
  for( var taskDesc in failedResults) {
    console.log( failedResults[taskDesc] + "\n" );
  }
}

function outputStatistic() {
  var failedTasks = Object.keys(failedResults).length
  var passedTasks = numberOfTasks - failedTasks;
  console.log( "*************************************" );
  console.log( "Total tasks ran: " + numberOfTasks );
  console.log( passedTasks + " Passed" );
  console.log( failedTasks + " Failed" );
  console.log( "*************************************" );
}
<|endoftext|>


<commit_before>var FuelAuth = require( 'fuel-auth' );
var FuelRest = require('fuel-rest');
var FuelSoap = require( 'fuel-soap' );

// Override the instance method
FuelRest.prototype.get = function(){
	//add a special header here indicating this is from the sdk.
	return FuelRest.prototype.get.call(this);
}

var ET_Client = {

	initAuth: function(id, secret) {

		// Initialization with extra options
		var accessToken  = "";
		var refreshToken = "";

		return new FuelAuth({
			clientId: id // required
			, clientSecret: secret // required
			, accessToken: accessToken
			, refreshToken: refreshToken
		});
	},

	initRest: function(id, secret) {
		var options  = {
			auth: {
				// options you want passed when Fuel Auth is initialized
				clientId: id
				, clientSecret: secret
			}
			//, origin: 'https://alternate.rest.endpoint.com' // default --> https://www.exacttargetapis.com
		};

		return new FuelRest(options);
	},

	initSoap: function(id, secret, stack) {
		stack = stack ? stack + '.' : '';
		var options = {
			auth: {
				clientId: id
				, clientSecret: secret
			}
			, soapEndpoint: 'https://webservice.'+ stack +'exacttarget.com/Service.asmx'
		};

		return new FuelSoap( options );
	},

};

module.exports = ET_Client;<commit_msg>comment some code<commit_after>var FuelAuth = require( 'fuel-auth' );
var FuelRest = require('fuel-rest');
var FuelSoap = require( 'fuel-soap' );

/*
// Override the instance method
FuelRest.prototype.get = function(){
	//add a special header here indicating this is from the sdk.
	return FuelRest.prototype.get.call(this);
}
*/

var ET_Client = {

	initAuth: function(id, secret) {

		// Initialization with extra options
		var accessToken  = "";
		var refreshToken = "";

		return new FuelAuth({
			clientId: id // required
			, clientSecret: secret // required
			, accessToken: accessToken
			, refreshToken: refreshToken
		});
	},

	initRest: function(id, secret) {
		var options  = {
			auth: {
				// options you want passed when Fuel Auth is initialized
				clientId: id
				, clientSecret: secret
			}
			//, origin: 'https://alternate.rest.endpoint.com' // default --> https://www.exacttargetapis.com
		};

		return new FuelRest(options);
	},

	initSoap: function(id, secret, stack) {
		stack = stack ? stack + '.' : '';
		var options = {
			auth: {
				clientId: id
				, clientSecret: secret
			}
			, soapEndpoint: 'https://webservice.'+ stack +'exacttarget.com/Service.asmx'
		};

		return new FuelSoap( options );
	},

};

module.exports = ET_Client;<|endoftext|>


<commit_before>/* FileSaver.js
 * A saveAs() FileSaver implementation.
 * 1.1.20150716
 *
 * By Eli Grey, http://eligrey.com
 * License: X11/MIT
 *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
 */

/*global self */
/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */

/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */

var saveAs = saveAs || (function(view) {
  "use strict";
  // IE <10 is explicitly unsupported
  if (typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
    return;
  }
  var
      doc = view.document
      // only get URL when necessary in case Blob.js hasn't overridden it yet
    , get_URL = function() {
      return view.URL || view.webkitURL || view;
    }
    , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
    , can_use_save_link = "download" in save_link
    , click = function(node) {
      var event = new MouseEvent("click");
      node.dispatchEvent(event);
    }
    , webkit_req_fs = view.webkitRequestFileSystem
    , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
    , throw_outside = function(ex) {
      (view.setImmediate || view.setTimeout)(function() {
        throw ex;
      }, 0);
    }
    , force_saveable_type = "application/octet-stream"
    , fs_min_size = 0
    // See https://code.google.com/p/chromium/issues/detail?id=375297#c7 and
    // https://github.com/eligrey/FileSaver.js/commit/485930a#commitcomment-8768047
    // for the reasoning behind the timeout and revocation flow
    , arbitrary_revoke_timeout = 500 // in ms
    , revoke = function(file) {
      var revoker = function() {
        if (typeof file === "string") { // file is an object URL
          get_URL().revokeObjectURL(file);
        } else { // file is a File
          file.remove();
        }
      };
      if (view.chrome) {
        revoker();
      } else {
        setTimeout(revoker, arbitrary_revoke_timeout);
      }
    }
    , dispatch = function(filesaver, event_types, event) {
      event_types = [].concat(event_types);
      var i = event_types.length;
      while (i--) {
        var listener = filesaver["on" + event_types[i]];
        if (typeof listener === "function") {
          try {
            listener.call(filesaver, event || filesaver);
          } catch (ex) {
            throw_outside(ex);
          }
        }
      }
    }
    , auto_bom = function(blob) {
      // prepend BOM for UTF-8 XML and text/* types (including HTML)
      if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
        return new Blob(["\ufeff", blob], {type: blob.type});
      }
      return blob;
    }
    , FileSaver = function(blob, name, no_auto_bom) {
      if (!no_auto_bom) {
        blob = auto_bom(blob);
      }
      // First try a.download, then web filesystem, then object URLs
      var
          filesaver = this
        , type = blob.type
        , blob_changed = false
        , object_url
        , target_view
        , dispatch_all = function() {
          dispatch(filesaver, "writestart progress write writeend".split(" "));
        }
        // on any filesys errors revert to saving with object URLs
        , fs_error = function() {
          // don't create more object URLs than needed
          if (blob_changed || !object_url) {
            object_url = get_URL().createObjectURL(blob);
          }
          if (target_view) {
            target_view.location.href = object_url;
          } else {
            var new_tab = view.open(object_url, "_blank");
            if (new_tab == undefined && typeof safari !== "undefined") {
              //Apple do not allow window.open, see http://bit.ly/1kZffRI
              view.location.href = object_url
            }
          }
          filesaver.readyState = filesaver.DONE;
          dispatch_all();
          revoke(object_url);
        }
        , abortable = function(func) {
          return function() {
            if (filesaver.readyState !== filesaver.DONE) {
              return func.apply(this, arguments);
            }
          };
        }
        , create_if_not_found = {create: true, exclusive: false}
        , slice
      ;
      filesaver.readyState = filesaver.INIT;
      if (!name) {
        name = "download";
      }
      if (can_use_save_link) {
        object_url = get_URL().createObjectURL(blob);
        save_link.href = object_url;
        save_link.download = name;
        setTimeout(function() {
          click(save_link);
          dispatch_all();
          revoke(object_url);
          filesaver.readyState = filesaver.DONE;
        });
        return;
      }
      // Object and web filesystem URLs have a problem saving in Google Chrome when
      // viewed in a tab, so I force save with application/octet-stream
      // http://code.google.com/p/chromium/issues/detail?id=91158
      // Update: Google errantly closed 91158, I submitted it again:
      // https://code.google.com/p/chromium/issues/detail?id=389642
      if (view.chrome && type && type !== force_saveable_type) {
        slice = blob.slice || blob.webkitSlice;
        blob = slice.call(blob, 0, blob.size, force_saveable_type);
        blob_changed = true;
      }
      // Since I can't be sure that the guessed media type will trigger a download
      // in WebKit, I append .download to the filename.
      // https://bugs.webkit.org/show_bug.cgi?id=65440
      if (webkit_req_fs && name !== "download") {
        name += ".download";
      }
      if (type === force_saveable_type || webkit_req_fs) {
        target_view = view;
      }
      if (!req_fs) {
        fs_error();
        return;
      }
      fs_min_size += blob.size;
      req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
        fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
          var save = function() {
            dir.getFile(name, create_if_not_found, abortable(function(file) {
              file.createWriter(abortable(function(writer) {
                writer.onwriteend = function(event) {
                  target_view.location.href = file.toURL();
                  filesaver.readyState = filesaver.DONE;
                  dispatch(filesaver, "writeend", event);
                  revoke(file);
                };
                writer.onerror = function() {
                  var error = writer.error;
                  if (error.code !== error.ABORT_ERR) {
                    fs_error();
                  }
                };
                "writestart progress write abort".split(" ").forEach(function(event) {
                  writer["on" + event] = filesaver["on" + event];
                });
                writer.write(blob);
                filesaver.abort = function() {
                  writer.abort();
                  filesaver.readyState = filesaver.DONE;
                };
                filesaver.readyState = filesaver.WRITING;
              }), fs_error);
            }), fs_error);
          };
          dir.getFile(name, {create: false}, abortable(function(file) {
            // delete file if it already exists
            file.remove();
            save();
          }), abortable(function(ex) {
            if (ex.code === ex.NOT_FOUND_ERR) {
              save();
            } else {
              fs_error();
            }
          }));
        }), fs_error);
      }), fs_error);
    }
    , FS_proto = FileSaver.prototype
    , saveAs = function(blob, name, no_auto_bom) {
      return new FileSaver(blob, name, no_auto_bom);
    }
  ;
  // IE 10+ (native saveAs)
  if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
    return function(blob, name, no_auto_bom) {
      if (!no_auto_bom) {
        blob = auto_bom(blob);
      }
      return navigator.msSaveOrOpenBlob(blob, name || "download");
    };
  }

  FS_proto.abort = function() {
    var filesaver = this;
    filesaver.readyState = filesaver.DONE;
    dispatch(filesaver, "abort");
  };
  FS_proto.readyState = FS_proto.INIT = 0;
  FS_proto.WRITING = 1;
  FS_proto.DONE = 2;

  FS_proto.error =
  FS_proto.onwritestart =
  FS_proto.onprogress =
  FS_proto.onwrite =
  FS_proto.onabort =
  FS_proto.onerror =
  FS_proto.onwriteend =
    null;

  return saveAs;
}(
     typeof self !== "undefined" && self
  || typeof window !== "undefined" && window
  || this.content
));
// `self` is undefined in Firefox for Android content script context
// while `this` is nsIContentFrameMessageManager
// with an attribute `content` that corresponds to the window

if (typeof module !== "undefined" && module.exports) {
  module.exports.saveAs = saveAs;
} else if ((typeof define !== "undefined" && define !== null) && (define.amd != null)) {
  define([], function() {
    return saveAs;
  });
}<commit_msg>Updates filesaver.js<commit_after>/* FileSaver.js
 * A saveAs() FileSaver implementation.
 * 1.1.20160328
 *
 * By Eli Grey, http://eligrey.com
 * License: MIT
 *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
 */

/*global self */
/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */

/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */

var saveAs = saveAs || (function(view) {
  "use strict";
  // IE <10 is explicitly unsupported
  if (typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
    return;
  }
  var
      doc = view.document
      // only get URL when necessary in case Blob.js hasn't overridden it yet
    , get_URL = function() {
      return view.URL || view.webkitURL || view;
    }
    , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
    , can_use_save_link = "download" in save_link
    , click = function(node) {
      var event = new MouseEvent("click");
      node.dispatchEvent(event);
    }
    , is_safari = /Version\/[\d\.]+.*Safari/.test(navigator.userAgent)
    , webkit_req_fs = view.webkitRequestFileSystem
    , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
    , throw_outside = function(ex) {
      (view.setImmediate || view.setTimeout)(function() {
        throw ex;
      }, 0);
    }
    , force_saveable_type = "application/octet-stream"
    , fs_min_size = 0
    // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
    , arbitrary_revoke_timeout = 1000 * 40 // in ms
    , revoke = function(file) {
      var revoker = function() {
        if (typeof file === "string") { // file is an object URL
          get_URL().revokeObjectURL(file);
        } else { // file is a File
          file.remove();
        }
      };
      /* // Take note W3C:
      var
        uri = typeof file === "string" ? file : file.toURL()
      , revoker = function(evt) {
        // idealy DownloadFinishedEvent.data would be the URL requested
        if (evt.data === uri) {
          if (typeof file === "string") { // file is an object URL
            get_URL().revokeObjectURL(file);
          } else { // file is a File
            file.remove();
          }
        }
      }
      ;
      view.addEventListener("downloadfinished", revoker);
      */
      setTimeout(revoker, arbitrary_revoke_timeout);
    }
    , dispatch = function(filesaver, event_types, event) {
      event_types = [].concat(event_types);
      var i = event_types.length;
      while (i--) {
        var listener = filesaver["on" + event_types[i]];
        if (typeof listener === "function") {
          try {
            listener.call(filesaver, event || filesaver);
          } catch (ex) {
            throw_outside(ex);
          }
        }
      }
    }
    , auto_bom = function(blob) {
      // prepend BOM for UTF-8 XML and text/* types (including HTML)
      if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
        return new Blob(["\ufeff", blob], {type: blob.type});
      }
      return blob;
    }
    , FileSaver = function(blob, name, no_auto_bom) {
      if (!no_auto_bom) {
        blob = auto_bom(blob);
      }
      // First try a.download, then web filesystem, then object URLs
      var
          filesaver = this
        , type = blob.type
        , blob_changed = false
        , object_url
        , target_view
        , dispatch_all = function() {
          dispatch(filesaver, "writestart progress write writeend".split(" "));
        }
        // on any filesys errors revert to saving with object URLs
        , fs_error = function() {
          if (target_view && is_safari && typeof FileReader !== "undefined") {
            // Safari doesn't allow downloading of blob urls
            var reader = new FileReader();
            reader.onloadend = function() {
              var base64Data = reader.result;
              target_view.location.href = "data:attachment/file" + base64Data.slice(base64Data.search(/[,;]/));
              filesaver.readyState = filesaver.DONE;
              dispatch_all();
            };
            reader.readAsDataURL(blob);
            filesaver.readyState = filesaver.INIT;
            return;
          }
          // don't create more object URLs than needed
          if (blob_changed || !object_url) {
            object_url = get_URL().createObjectURL(blob);
          }
          if (target_view) {
            target_view.location.href = object_url;
          } else {
            var new_tab = view.open(object_url, "_blank");
            if (new_tab === undefined && is_safari) {
              //Apple do not allow window.open, see http://bit.ly/1kZffRI
              view.location.href = object_url
            }
          }
          filesaver.readyState = filesaver.DONE;
          dispatch_all();
          revoke(object_url);
        }
        , abortable = function(func) {
          return function() {
            if (filesaver.readyState !== filesaver.DONE) {
              return func.apply(this, arguments);
            }
          };
        }
        , create_if_not_found = {create: true, exclusive: false}
        , slice
      ;
      filesaver.readyState = filesaver.INIT;
      if (!name) {
        name = "download";
      }
      if (can_use_save_link) {
        object_url = get_URL().createObjectURL(blob);
        setTimeout(function() {
          save_link.href = object_url;
          save_link.download = name;
          click(save_link);
          dispatch_all();
          revoke(object_url);
          filesaver.readyState = filesaver.DONE;
        });
        return;
      }
      // Object and web filesystem URLs have a problem saving in Google Chrome when
      // viewed in a tab, so I force save with application/octet-stream
      // http://code.google.com/p/chromium/issues/detail?id=91158
      // Update: Google errantly closed 91158, I submitted it again:
      // https://code.google.com/p/chromium/issues/detail?id=389642
      if (view.chrome && type && type !== force_saveable_type) {
        slice = blob.slice || blob.webkitSlice;
        blob = slice.call(blob, 0, blob.size, force_saveable_type);
        blob_changed = true;
      }
      // Since I can't be sure that the guessed media type will trigger a download
      // in WebKit, I append .download to the filename.
      // https://bugs.webkit.org/show_bug.cgi?id=65440
      if (webkit_req_fs && name !== "download") {
        name += ".download";
      }
      if (type === force_saveable_type || webkit_req_fs) {
        target_view = view;
      }
      if (!req_fs) {
        fs_error();
        return;
      }
      fs_min_size += blob.size;
      req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
        fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
          var save = function() {
            dir.getFile(name, create_if_not_found, abortable(function(file) {
              file.createWriter(abortable(function(writer) {
                writer.onwriteend = function(event) {
                  target_view.location.href = file.toURL();
                  filesaver.readyState = filesaver.DONE;
                  dispatch(filesaver, "writeend", event);
                  revoke(file);
                };
                writer.onerror = function() {
                  var error = writer.error;
                  if (error.code !== error.ABORT_ERR) {
                    fs_error();
                  }
                };
                "writestart progress write abort".split(" ").forEach(function(event) {
                  writer["on" + event] = filesaver["on" + event];
                });
                writer.write(blob);
                filesaver.abort = function() {
                  writer.abort();
                  filesaver.readyState = filesaver.DONE;
                };
                filesaver.readyState = filesaver.WRITING;
              }), fs_error);
            }), fs_error);
          };
          dir.getFile(name, {create: false}, abortable(function(file) {
            // delete file if it already exists
            file.remove();
            save();
          }), abortable(function(ex) {
            if (ex.code === ex.NOT_FOUND_ERR) {
              save();
            } else {
              fs_error();
            }
          }));
        }), fs_error);
      }), fs_error);
    }
    , FS_proto = FileSaver.prototype
    , saveAs = function(blob, name, no_auto_bom) {
      return new FileSaver(blob, name, no_auto_bom);
    }
  ;
  // IE 10+ (native saveAs)
  if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
    return function(blob, name, no_auto_bom) {
      if (!no_auto_bom) {
        blob = auto_bom(blob);
      }
      return navigator.msSaveOrOpenBlob(blob, name || "download");
    };
  }

  FS_proto.abort = function() {
    var filesaver = this;
    filesaver.readyState = filesaver.DONE;
    dispatch(filesaver, "abort");
  };
  FS_proto.readyState = FS_proto.INIT = 0;
  FS_proto.WRITING = 1;
  FS_proto.DONE = 2;

  FS_proto.error =
  FS_proto.onwritestart =
  FS_proto.onprogress =
  FS_proto.onwrite =
  FS_proto.onabort =
  FS_proto.onerror =
  FS_proto.onwriteend =
    null;

  return saveAs;
}(
     typeof self !== "undefined" && self
  || typeof window !== "undefined" && window
  || this.content
));
// `self` is undefined in Firefox for Android content script context
// while `this` is nsIContentFrameMessageManager
// with an attribute `content` that corresponds to the window

if (typeof module !== "undefined" && module.exports) {
  module.exports.saveAs = saveAs;
} else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) {
  define([], function() {
    return saveAs;
  });
}<|endoftext|>


<commit_before>import React from "react";
import PropTypes from 'prop-types';
import {activeColumnKeys as activeColumnKeysFunction} from './utils';
import TextFilter from './TextFilter';

const DefaultFilterRowComponent = ({children, ...restProps}) =>
{children}
;

class FilterRow extends React.Component {
  constructor(props) {
    super(props);
  }

  shouldComponentUpdate(nextContext){
      return this.context !== nextContext;
  }

  render() {
      const {component, children} = this.props;
      const {objects, columnConfigs, filter, updateFilter} = this.context;
      const activeColumnKeys = activeColumnKeysFunction(columnConfigs);
      const FilterRowComponent = component ? component : DefaultFilterRowComponent ;
      const activeFilters = activeColumnKeys.filter(columnKey => !columnConfigs.find(c => c.name === columnKey).hideTools );
      return (
        <FilterRowComponent>
            {activeColumnKeys.map(columnKey => {
                if (activeFilters.indexOf(columnKey) !== -1){
                    const currentConfig = columnConfigs.find(c => c.name === columnKey);
                    const FilterComponent = currentConfig.filterComponent
                        ? columnConfigs[columnKey].filterComponent : TextFilter;
                    const currentFilter = filter.find(currentFilter => currentFilter.columnName === columnKey);
                    const query = currentFilter && currentFilter.expression ? currentFilter.expression : "";

                    return(

                            <FilterComponent updateFilter={(newExpression) => {updateFilter({columnName: columnKey, expression: newExpression})}} column={columnKey} query={query}/>
                        	)
                } else {
                    return(	)
                }
            })
            }
        </FilterRowComponent>
    );
  }
}
FilterRow.contextTypes = {
    objects: PropTypes.array.isRequired,
    columnConfigs: PropTypes.array,
    filter: PropTypes.array,
    updateFilter: PropTypes.func
};

export default FilterRow;
<commit_msg>refine types<commit_after>import React from "react";
import PropTypes from 'prop-types';
import {activeColumnKeys as activeColumnKeysFunction} from './utils';
import TextFilter from './TextFilter';

const DefaultFilterRowComponent = ({children, ...restProps}) =>
{children}
;

class FilterRow extends React.Component {
  constructor(props) {
    super(props);
  }

  shouldComponentUpdate(nextContext){
      return this.context !== nextContext;
  }

  render() {
      const {component, children} = this.props;
      const {objects, columnConfigs, filter, updateFilter} = this.context;
      const activeColumnKeys = activeColumnKeysFunction(columnConfigs);
      const FilterRowComponent = component ? component : DefaultFilterRowComponent ;
      const activeFilters = activeColumnKeys.filter(columnKey => !columnConfigs.find(c => c.name === columnKey).hideTools );
      return (
        <FilterRowComponent>
            {activeColumnKeys.map(columnKey => {
                if (activeFilters.indexOf(columnKey) !== -1){
                    const currentConfig = columnConfigs.find(c => c.name === columnKey);
                    const FilterComponent = currentConfig.filterComponent
                        ? columnConfigs[columnKey].filterComponent : TextFilter;
                    const currentFilter = filter.find(currentFilter => currentFilter.columnName === columnKey);
                    const query = currentFilter && currentFilter.expression ? currentFilter.expression : "";

                    return(

                            <FilterComponent updateFilter={(newExpression) => {updateFilter({columnName: columnKey, expression: newExpression})}} column={columnKey} query={query}/>
                        	)
                } else {
                    return(	)
                }
            })
            }
        </FilterRowComponent>
    );
  }
}
FilterRow.contextTypes = {
    objects: PropTypes.array.isRequired,
    columnConfigs: PropTypes.array,
    filter: PropTypes.array,
    updateFilter: PropTypes.func.isRequired
};

if (process.env.NODE_ENV !== 'production'){
  FilterRow.propTypes = {
      component: PropTypes.func
  }
}

export default FilterRow;
<|endoftext|>


<commit_before>(function (angular) {
    "use strict";

    angular.module('scope-aware', [])
        .service('Inspector', ['$rootScope', function ($rootScope) {

            var getChildScopes = function(scope) {
                if (typeof scope.$$childHead === 'undefined') {
                    return [];
                }
                var allChildren = [];
                var child = scope.$$childHead;
                while (child !== null) {
                    allChildren.push(child);
                    child = child.$$nextSibling;
                }
                return allChildren;
            };

            var grabElement = function(id, element) {
                var el = angular.element(element);
                var scope = el.isolateScope() || el.scope();
                if(scope && scope.$id === id) {
                    return el;
                } else {
                    for(var i=0;i<element.childNodes.length; i++) {
                        var subEl = grabElement(id, element.childNodes[i]);
                        if(typeof subEl !== 'undefined') {
                            return subEl;
                        }
                    }
                }
            };

            var guessAngularDir = function(element) {
                if(element) {
                    var possibleDir = ['ng-repeat', 'ng-include', 'ng-transclude', 'ng-view', 'ng-switch', 'ng-controller'];
                    for(var i=0;i<possibleDir.length;i++) {
                        if(element.attr(possibleDir[i])) {
                            return possibleDir[i];
                        }
                    }
                }
            };

            var getProto = function(obj) {
                if(typeof Object.getPrototypeOf !== 'undefined') {
                    return Object.getPrototypeOf(obj);
                }
                /* jshint proto: true */
                return obj.__proto__;
            };

            var hasPrimitivePropInScopeChain = function(proto,prop) {
                if(proto === null) {
                    return false;
                }
                if(proto.hasOwnProperty(prop)) {
                    return !(angular.isObject(proto[prop]) || angular.isFunction(proto[prop]));
                } else {
                    return hasPrimitivePropInScopeChain.call(null,getProto(proto),prop);
                }
            };

            var grabScopeMembers = function (anyScope, inheritedProps, onlyPrimitives) {
                var cleanScope = {};
                for (var p in anyScope) {
                    if (p.indexOf('$') === 0 || p === 'this' || p === 'constructor') {
                        continue;
                    }
                    if(typeof inheritedProps !== 'undefined') {
                        if(anyScope.$$isolateBindings === null || typeof anyScope.$$isolateBindings[p] === 'undefined') {
                            if (!anyScope.hasOwnProperty(p)) {
                                var doAdd = true;
                                if (onlyPrimitives === true) {
                                    doAdd = !(angular.isObject(anyScope[p]) || angular.isFunction(anyScope[p]));
                                }
                                if (doAdd === true) {
                                    inheritedProps[p] = true;
                                }
                            }
                        }
                    }
                    cleanScope[p] = anyScope[p];
                }
                return cleanScope;
            };

            var traverse = function (anyScope, visitor, lvl) {
                lvl = lvl || 0;
                var i = 0, lvlStr = '', str = '';
                while (i < lvl) {
                    lvlStr += '  ';
                    i++;
                }
                var element = grabElement(anyScope.$id, document.body);
                var dir = guessAngularDir(element);
                var info = (element && element.length > 0) ? ' <' + element[0].nodeName + '>' + (dir ? ' ' + dir : '') : '';
                str += lvlStr + '[+]-' + anyScope.$id + info + '\n';
                var inheritedProps = {};
                var grabbedData = grabScopeMembers(anyScope, inheritedProps);
                if (typeof visitor === 'function') {
                    visitor.apply(null, [anyScope.$id, grabbedData]);
                }
                var data = JSON.stringify(grabbedData,
                    function (key, val) {
                        //skip angular properties
                        if(key.indexOf && key.indexOf('$') === 0) {
                            return undefined;
                        }
                        if (typeof val === 'function') {
                            var fun = val + '';
                            var args = /\(.*\)/g.exec(fun)[0].replace(/^\(/g, '').replace(/\)$/g, '').split(',');
                            return 'function(' + args.join(',') + ') { ... }';
                        }
                        return val;
                    }, '\t');
                var pieces = data.split('\n');
                var formattedData = '';
                angular.forEach(pieces, function (value) {
                    var inherited = /^\t"(\w+)"\s*\:/g.exec(value);
                    var marker = '';
                    if (inherited && inherited[1]) {
                        if(inheritedProps[inherited[1]]) {
                            marker += 'inherited property';
                        }
                        if(hasPrimitivePropInScopeChain(getProto(anyScope),inherited[1])) {
                            if(marker.length > 0) {
                                marker += '; ';
                            }
                            marker += anyScope.hasOwnProperty(inherited[1]) ? ' shadowed !!!' : ' shadowing danger';
                        }
                    }
                    if(marker !== '') {
                        marker = ' <------ ' + marker;
                    }
                    formattedData += lvlStr + ' |     ' + value + marker + '\n';
                });
                str += formattedData;

                angular.forEach(getChildScopes(anyScope), function (value) {
                    str += traverse(value, visitor, lvl + 1);
                });
                return str;
            };

            return {
                grabScopeMembers : grabScopeMembers,
                grabElement: grabElement,
                guessAngularDir: guessAngularDir,
                getProto: getProto,
                hasPrimitivePropInScopeChain: hasPrimitivePropInScopeChain,
                getChildScopes: getChildScopes,
                inspect: function (scope, visitor) {
                    return traverse(scope || $rootScope, visitor);
                }
            };
        }])
        .service('Monitor',['Inspector', function(Inspector) {
            var toString = function(obj) {
                var str = '';
                var t = typeof obj;
                if(t === 'string' || t === 'number') {
                    str += obj;
                } else
                if(angular.isArray(obj)) {
                    str += '[';
                    angular.forEach(obj, function(val,idx) {
                        if(idx > 0) {
                            str += ',';
                        }
                        str += idx + '=' + toString(val);
                    });
                    str += ']';
                }  else
                if(t === 'object') {
                    str += '{';
                    var count = 0;
                    angular.forEach(obj, function(val,key) {
                        var keyStr = toString(key);
                        if(count++ > 0) {
                            str += ';';
                        }
                        str += keyStr + '=' + toString(val);
                    });
                    str += '}';
                }
                return str;
            };

            var hashcode = function(str) {
                var hash = 0;
                if(!str) return hash;
                for(var i = 0; i < str.length; i++) {
                    var chr   = str.charCodeAt(i);
                    hash  = ((hash << 5) - hash) + chr;
                    hash |= 0; // Convert to 32bit integer
                }
                return hash;
            };

            var scopeHashes = {};
            var monitor = function(scope, state) {
                if(typeof state !== 'undefined') {
                    state.running = true;
                }
                var inheritedMembers = {};
                var members = Inspector.grabScopeMembers(scope, inheritedMembers, true);
                var str = toString(members);
                var hc = hashcode(str);
                if(!scopeHashes[scope.$id]) {
                    scopeHashes[scope.$id] = hc;
                } else {
                    if(scopeHashes[scope.$id] !== hc) {
                        var shadowed = {};
                        var isolatedBindings = scope.$$isolateBindings || {};
                        members.forEach(function(member) {
                            if(scope.hasOwnProperty(member) &&
                                typeof isolatedBindings[member] === 'undefined' &&
                                Inspector.hasPrimitivePropInScopeChain(Inspector.getProto(scope),member) === true) {
                                shadowed[member] = true;
                            }
                        });
                        if(shadowed.length > 0) {
                            $window.warn('members shadowed: ');
                            $window.warn(Object.keys(shadowed));
                        }
                        var possiblyShadowed = {};
                        inheritedMembers.forEach(function(member) {
                            if(shadowed[member] !== true) {
                                possiblyShadowed[member] = true;
                            }
                        });
                        if(possiblyShadowed.length > 0) {
                            $window.warn('members could be shadowed: ');
                            $window.warn(Object.keys(possiblyShadowed));
                        }
                    }
                }

                var children = Inspector.getChildScopes(scope);
                angular.forEach(children, function (child) {
                    monitor(child, state);
                });
            };

            return {
                toString: toString,
                hashcode: hashcode,
                monitor: monitor
            };
        }])
        .service('MiniTemplateEngine', [ function() {
            return {
                fill: function(tpl) {
                    var values = Array.prototype.slice.call(arguments);
                    var rep = tpl.replace(/\{\{[1-9]+\}\}/g, function(m, offset, str) {
                        var idx = parseInt(m.replace(/\{/g,'').replace(/\}/g,''),10);
                        var val = values[idx];
                        return val;
                    });
                    return rep;
                }
            };
        }])
        .service('JasmineMatchersFactory', ['Inspector', 'MiniTemplateEngine', function(Inspector, MiniTemplateEngine) {

            var checkScope = function(scope) {
                if(!scope) {
                    throw new Error('scope should be an object');
                }
                if(!scope.$id) {
                    throw new Error('actual should be an angular scope');
                }
            };
            var convertArgs = function() {
                return Array.prototype.concat.apply([],arguments).slice(1);
            };
            var compareArraysAndTrace = function(id, actual, expected, msgPass, msgFail) {
                var missingMembers = [];
                expected.forEach(function(member) {
                    if(actual.indexOf(member) === -1) {
                        missingMembers.push(member);
                    }
                });
                var result = {};
                result.pass = (missingMembers.length === 0);
                if (result.pass) {
                    result.message = MiniTemplateEngine.fill(msgPass, id, expected);
                } else {
                    result.message = MiniTemplateEngine.fill(msgFail, id, actual, expected, missingMembers);
                }
                return result;
            };

            var toHaveMembers = function(util, customEqualityTesters) {
                return {
                    compare: function(actual, expected) {
                        checkScope(actual);
                        expected = convertArgs.apply(null,arguments);

                        var allMembers = Inspector.grabScopeMembers(actual);
                        var msgPass = 'Scope with ID {{1}} has members ({{2}})';
                        var msgFail = 'Expected scope with ID {{1}} and members [{{2}}] to have members [{{3}}]. Missing members are: [{{4}}]';
                        return compareArraysAndTrace(actual.$id, Object.keys(allMembers), expected, msgPass, msgFail);
                    }
                };
            };
            var toHaveInheritedMembers = function(util, customEqualityTesters) {
                return {
                    compare: function(actual, expected) {
                        checkScope(actual);
                        expected = convertArgs.apply(null,arguments);

                        var inheritedMembers = {};
                        Inspector.grabScopeMembers(actual, inheritedMembers);
                        var msgPass = 'Scope with ID {{1}} has inherited members ({{2}})';
                        var msgFail = 'Expected scope with ID {{1}} and inherited members [{{2}}] to have inherited members [{{3}}]. Missing members are: [{{4}}]';
                        return compareArraysAndTrace(actual.$id, Object.keys(inheritedMembers), expected, msgPass, msgFail);
                    }
                };
            };
            var toBeCleanScope = function(util, customEqualityTesters) {
                return {
                    compare: function(actual) {
                        var allMembers = Inspector.grabScopeMembers(actual);
                        var result = { pass : true };
                        for(var token in allMembers) {
                            result.pass = false;
                            break;
                        }
                        if (result.pass) {
                            result.message = 'Scope with ID ' + actual.$id + ' is clean';
                        } else {
                            result.message = 'Expected scope with ID ' + actual.$id + ' to be clean';
                        }
                        return result;
                    }
                };
            };
            var toHaveChildScopes = function(util, customEqualityTesters) {
                return {
                    compare: function(actual) {
                        var result = { pass : !!actual.$$childHead };
                        if (result.pass) {
                            result.message = 'Scope with ID ' + actual.$id + ' has at least one child scope';
                        } else {
                            result.message = 'Expected scope with ID ' + actual.$id + ' to have some child scopes';
                        }
                        return result;
                    }
                };
            };
            var toPossiblyShadow = function(util, customEqualityTesters) {
                return {
                    compare: function(actual, expected) {
                        checkScope(actual);
                        expected = convertArgs.apply(null,arguments);

                        var inheritedMembers = {};
                        //only primitives can be shadowed ==> pass true
                        Inspector.grabScopeMembers(actual, inheritedMembers, true);

                        var msgPass = 'Scope with ID {{1}} can possibly shadow inherited properties ({{2}})';
                        var msgFail = 'Expected scope with ID {{1}} and inherited members [{{2}}] to possibly shadow members [{{3}}]. Missing members are: [{{4}}]';
                        return compareArraysAndTrace(actual.$id, Object.keys(inheritedMembers), expected, msgPass, msgFail);
                    }
                };
            };
            var toShadow = function(util, customEqualityTesters) {
                return {
                    compare: function(actual, expected) {
                        checkScope(actual);
                        expected = convertArgs.apply(null,arguments);

                        var shadowed = [];
                        var isolatedBindings = actual.$$isolateBindings || {};
                        expected.forEach(function(member) {
                            if(actual.hasOwnProperty(member) &&
                               typeof isolatedBindings[member] === 'undefined' &&
                               Inspector.hasPrimitivePropInScopeChain(Inspector.getProto(actual),member) === true) {
                                shadowed.push(member);
                            }
                        });
                        var msgPass = 'Scope with ID {{1}} is shadowing inherited properties ({{2}})';
                        var msgFail = 'Expected scope with ID {{1}} and inherited members [{{2}}] to shadow members [{{3}}]. Missing members are: [{{4}}]';
                        return compareArraysAndTrace(actual.$id, shadowed, expected, msgPass, msgFail);
                    }
                };
            };
            return {
                create : function() {
                    return {
                        toHaveMembers: toHaveMembers,
                        toHaveInheritedMembers: toHaveInheritedMembers,
                        toBeCleanScope: toBeCleanScope,
                        toHaveChildScopes: toHaveChildScopes,
                        toPossiblyShadow: toPossiblyShadow,
                        toShadow: toShadow
                    };
                }
            };
        }])
        .run(['$window','$rootScope', 'Monitor', function($window, $rootScope, Monitor) {
            var state = {running : false};
            $window.setInterval(function() {
                if(state.running === false) {
                    Monitor.monitor($rootScope, state);
                    state.running = false;
                }
            }, 2000);
        }]);

    if(typeof jasmine != 'undefined' && typeof beforeEach === 'function') {
        var $injector = angular.bootstrap(window, ['scope-aware']);
        var JasmineMatchersFactory = $injector.get('JasmineMatchersFactory');
        var matchers = JasmineMatchersFactory.create();
        beforeEach(function() {
            jasmine.addMatchers(matchers);
        });
    }
})(angular);<commit_msg>bug-fix: proper check whether the object is empty<commit_after>(function (angular) {
    "use strict";

    angular.module('scope-aware', [])
        .service('Inspector', ['$rootScope', function ($rootScope) {

            var getChildScopes = function(scope) {
                if (typeof scope.$$childHead === 'undefined') {
                    return [];
                }
                var allChildren = [];
                var child = scope.$$childHead;
                while (child !== null) {
                    allChildren.push(child);
                    child = child.$$nextSibling;
                }
                return allChildren;
            };

            var grabElement = function(id, element) {
                var el = angular.element(element);
                var scope = el.isolateScope() || el.scope();
                if(scope && scope.$id === id) {
                    return el;
                } else {
                    for(var i=0;i<element.childNodes.length; i++) {
                        var subEl = grabElement(id, element.childNodes[i]);
                        if(typeof subEl !== 'undefined') {
                            return subEl;
                        }
                    }
                }
            };

            var guessAngularDir = function(element) {
                if(element) {
                    var possibleDir = ['ng-repeat', 'ng-include', 'ng-transclude', 'ng-view', 'ng-switch', 'ng-controller'];
                    for(var i=0;i<possibleDir.length;i++) {
                        if(element.attr(possibleDir[i])) {
                            return possibleDir[i];
                        }
                    }
                }
            };

            var getProto = function(obj) {
                if(typeof Object.getPrototypeOf !== 'undefined') {
                    return Object.getPrototypeOf(obj);
                }
                /* jshint proto: true */
                return obj.__proto__;
            };

            var hasPrimitivePropInScopeChain = function(proto,prop) {
                if(proto === null) {
                    return false;
                }
                if(proto.hasOwnProperty(prop)) {
                    return !(angular.isObject(proto[prop]) || angular.isFunction(proto[prop]));
                } else {
                    return hasPrimitivePropInScopeChain.call(null,getProto(proto),prop);
                }
            };

            var grabScopeMembers = function (anyScope, inheritedProps, onlyPrimitives) {
                var cleanScope = {};
                for (var p in anyScope) {
                    if (p.indexOf('$') === 0 || p === 'this' || p === 'constructor') {
                        continue;
                    }
                    if(typeof inheritedProps !== 'undefined') {
                        if(anyScope.$$isolateBindings === null || typeof anyScope.$$isolateBindings[p] === 'undefined') {
                            if (!anyScope.hasOwnProperty(p)) {
                                var doAdd = true;
                                if (onlyPrimitives === true) {
                                    doAdd = !(angular.isObject(anyScope[p]) || angular.isFunction(anyScope[p]));
                                }
                                if (doAdd === true) {
                                    inheritedProps[p] = true;
                                }
                            }
                        }
                    }
                    cleanScope[p] = anyScope[p];
                }
                return cleanScope;
            };

            var traverse = function (anyScope, visitor, lvl) {
                lvl = lvl || 0;
                var i = 0, lvlStr = '', str = '';
                while (i < lvl) {
                    lvlStr += '  ';
                    i++;
                }
                var element = grabElement(anyScope.$id, document.body);
                var dir = guessAngularDir(element);
                var info = (element && element.length > 0) ? ' <' + element[0].nodeName + '>' + (dir ? ' ' + dir : '') : '';
                str += lvlStr + '[+]-' + anyScope.$id + info + '\n';
                var inheritedProps = {};
                var grabbedData = grabScopeMembers(anyScope, inheritedProps);
                if (typeof visitor === 'function') {
                    visitor.apply(null, [anyScope.$id, grabbedData]);
                }
                var data = JSON.stringify(grabbedData,
                    function (key, val) {
                        //skip angular properties
                        if(key.indexOf && key.indexOf('$') === 0) {
                            return undefined;
                        }
                        if (typeof val === 'function') {
                            var fun = val + '';
                            var args = /\(.*\)/g.exec(fun)[0].replace(/^\(/g, '').replace(/\)$/g, '').split(',');
                            return 'function(' + args.join(',') + ') { ... }';
                        }
                        return val;
                    }, '\t');
                var pieces = data.split('\n');
                var formattedData = '';
                angular.forEach(pieces, function (value) {
                    var inherited = /^\t"(\w+)"\s*\:/g.exec(value);
                    var marker = '';
                    if (inherited && inherited[1]) {
                        if(inheritedProps[inherited[1]]) {
                            marker += 'inherited property';
                        }
                        if(hasPrimitivePropInScopeChain(getProto(anyScope),inherited[1])) {
                            if(marker.length > 0) {
                                marker += '; ';
                            }
                            marker += anyScope.hasOwnProperty(inherited[1]) ? ' shadowed !!!' : ' shadowing danger';
                        }
                    }
                    if(marker !== '') {
                        marker = ' <------ ' + marker;
                    }
                    formattedData += lvlStr + ' |     ' + value + marker + '\n';
                });
                str += formattedData;

                angular.forEach(getChildScopes(anyScope), function (value) {
                    str += traverse(value, visitor, lvl + 1);
                });
                return str;
            };

            return {
                grabScopeMembers : grabScopeMembers,
                grabElement: grabElement,
                guessAngularDir: guessAngularDir,
                getProto: getProto,
                hasPrimitivePropInScopeChain: hasPrimitivePropInScopeChain,
                getChildScopes: getChildScopes,
                inspect: function (scope, visitor) {
                    return traverse(scope || $rootScope, visitor);
                }
            };
        }])
        .service('Monitor',['Inspector', function(Inspector) {
            var toString = function(obj) {
                var str = '';
                var t = typeof obj;
                if(t === 'string' || t === 'number') {
                    str += obj;
                } else
                if(angular.isArray(obj)) {
                    str += '[';
                    angular.forEach(obj, function(val,idx) {
                        if(idx > 0) {
                            str += ',';
                        }
                        str += idx + '=' + toString(val);
                    });
                    str += ']';
                }  else
                if(t === 'object') {
                    str += '{';
                    var count = 0;
                    angular.forEach(obj, function(val,key) {
                        var keyStr = toString(key);
                        if(count++ > 0) {
                            str += ';';
                        }
                        str += keyStr + '=' + toString(val);
                    });
                    str += '}';
                }
                return str;
            };

            var hashcode = function(str) {
                var hash = 0;
                if(!str) return hash;
                for(var i = 0; i < str.length; i++) {
                    var chr   = str.charCodeAt(i);
                    hash  = ((hash << 5) - hash) + chr;
                    hash |= 0; // Convert to 32bit integer
                }
                return hash;
            };
            var isEmptyObj = function(obj) {
                for(var attr in obj) {
                    return false;
                }
                return true;
            };

            var scopeHashes = {};
            var monitor = function(scope, state) {
                if(typeof state !== 'undefined') {
                    state.running = true;
                }
                var inheritedMembers = {};
                var members = Inspector.grabScopeMembers(scope, inheritedMembers, true);
                var str = toString(members);
                var hc = hashcode(str);
                if(!scopeHashes[scope.$id]) {
                    scopeHashes[scope.$id] = hc;
                } else {
                    if(scopeHashes[scope.$id] !== hc) {
                        var shadowed = {};
                        var isolatedBindings = scope.$$isolateBindings || {};
                        members.forEach(function(member) {
                            if(scope.hasOwnProperty(member) &&
                                typeof isolatedBindings[member] === 'undefined' &&
                                Inspector.hasPrimitivePropInScopeChain(Inspector.getProto(scope),member) === true) {
                                shadowed[member] = true;
                            }
                        });
                        if(!isEmptyObj(shadowed)) {
                            $window.warn('members shadowed: ');
                            $window.warn(Object.keys(shadowed));
                        }
                        var possiblyShadowed = {};
                        inheritedMembers.forEach(function(member) {
                            if(shadowed[member] !== true) {
                                possiblyShadowed[member] = true;
                            }
                        });
                        if(!isEmptyObj(possiblyShadowed)) {
                            $window.warn('members could be shadowed: ');
                            $window.warn(Object.keys(possiblyShadowed));
                        }
                    }
                }

                var children = Inspector.getChildScopes(scope);
                angular.forEach(children, function (child) {
                    monitor(child, state);
                });
            };

            return {
                toString: toString,
                hashcode: hashcode,
                monitor: monitor
            };
        }])
        .service('MiniTemplateEngine', [ function() {
            return {
                fill: function(tpl) {
                    var values = Array.prototype.slice.call(arguments);
                    var rep = tpl.replace(/\{\{[1-9]+\}\}/g, function(m, offset, str) {
                        var idx = parseInt(m.replace(/\{/g,'').replace(/\}/g,''),10);
                        var val = values[idx];
                        return val;
                    });
                    return rep;
                }
            };
        }])
        .service('JasmineMatchersFactory', ['Inspector', 'MiniTemplateEngine', function(Inspector, MiniTemplateEngine) {

            var checkScope = function(scope) {
                if(!scope) {
                    throw new Error('scope should be an object');
                }
                if(!scope.$id) {
                    throw new Error('actual should be an angular scope');
                }
            };
            var convertArgs = function() {
                return Array.prototype.concat.apply([],arguments).slice(1);
            };
            var compareArraysAndTrace = function(id, actual, expected, msgPass, msgFail) {
                var missingMembers = [];
                expected.forEach(function(member) {
                    if(actual.indexOf(member) === -1) {
                        missingMembers.push(member);
                    }
                });
                var result = {};
                result.pass = (missingMembers.length === 0);
                if (result.pass) {
                    result.message = MiniTemplateEngine.fill(msgPass, id, expected);
                } else {
                    result.message = MiniTemplateEngine.fill(msgFail, id, actual, expected, missingMembers);
                }
                return result;
            };

            var toHaveMembers = function(util, customEqualityTesters) {
                return {
                    compare: function(actual, expected) {
                        checkScope(actual);
                        expected = convertArgs.apply(null,arguments);

                        var allMembers = Inspector.grabScopeMembers(actual);
                        var msgPass = 'Scope with ID {{1}} has members ({{2}})';
                        var msgFail = 'Expected scope with ID {{1}} and members [{{2}}] to have members [{{3}}]. Missing members are: [{{4}}]';
                        return compareArraysAndTrace(actual.$id, Object.keys(allMembers), expected, msgPass, msgFail);
                    }
                };
            };
            var toHaveInheritedMembers = function(util, customEqualityTesters) {
                return {
                    compare: function(actual, expected) {
                        checkScope(actual);
                        expected = convertArgs.apply(null,arguments);

                        var inheritedMembers = {};
                        Inspector.grabScopeMembers(actual, inheritedMembers);
                        var msgPass = 'Scope with ID {{1}} has inherited members ({{2}})';
                        var msgFail = 'Expected scope with ID {{1}} and inherited members [{{2}}] to have inherited members [{{3}}]. Missing members are: [{{4}}]';
                        return compareArraysAndTrace(actual.$id, Object.keys(inheritedMembers), expected, msgPass, msgFail);
                    }
                };
            };
            var toBeCleanScope = function(util, customEqualityTesters) {
                return {
                    compare: function(actual) {
                        var allMembers = Inspector.grabScopeMembers(actual);
                        var result = { pass : true };
                        for(var token in allMembers) {
                            result.pass = false;
                            break;
                        }
                        if (result.pass) {
                            result.message = 'Scope with ID ' + actual.$id + ' is clean';
                        } else {
                            result.message = 'Expected scope with ID ' + actual.$id + ' to be clean';
                        }
                        return result;
                    }
                };
            };
            var toHaveChildScopes = function(util, customEqualityTesters) {
                return {
                    compare: function(actual) {
                        var result = { pass : !!actual.$$childHead };
                        if (result.pass) {
                            result.message = 'Scope with ID ' + actual.$id + ' has at least one child scope';
                        } else {
                            result.message = 'Expected scope with ID ' + actual.$id + ' to have some child scopes';
                        }
                        return result;
                    }
                };
            };
            var toPossiblyShadow = function(util, customEqualityTesters) {
                return {
                    compare: function(actual, expected) {
                        checkScope(actual);
                        expected = convertArgs.apply(null,arguments);

                        var inheritedMembers = {};
                        //only primitives can be shadowed ==> pass true
                        Inspector.grabScopeMembers(actual, inheritedMembers, true);

                        var msgPass = 'Scope with ID {{1}} can possibly shadow inherited properties ({{2}})';
                        var msgFail = 'Expected scope with ID {{1}} and inherited members [{{2}}] to possibly shadow members [{{3}}]. Missing members are: [{{4}}]';
                        return compareArraysAndTrace(actual.$id, Object.keys(inheritedMembers), expected, msgPass, msgFail);
                    }
                };
            };
            var toShadow = function(util, customEqualityTesters) {
                return {
                    compare: function(actual, expected) {
                        checkScope(actual);
                        expected = convertArgs.apply(null,arguments);

                        var shadowed = [];
                        var isolatedBindings = actual.$$isolateBindings || {};
                        expected.forEach(function(member) {
                            if(actual.hasOwnProperty(member) &&
                               typeof isolatedBindings[member] === 'undefined' &&
                               Inspector.hasPrimitivePropInScopeChain(Inspector.getProto(actual),member) === true) {
                                shadowed.push(member);
                            }
                        });
                        var msgPass = 'Scope with ID {{1}} is shadowing inherited properties ({{2}})';
                        var msgFail = 'Expected scope with ID {{1}} and inherited members [{{2}}] to shadow members [{{3}}]. Missing members are: [{{4}}]';
                        return compareArraysAndTrace(actual.$id, shadowed, expected, msgPass, msgFail);
                    }
                };
            };
            return {
                create : function() {
                    return {
                        toHaveMembers: toHaveMembers,
                        toHaveInheritedMembers: toHaveInheritedMembers,
                        toBeCleanScope: toBeCleanScope,
                        toHaveChildScopes: toHaveChildScopes,
                        toPossiblyShadow: toPossiblyShadow,
                        toShadow: toShadow
                    };
                }
            };
        }])
        .run(['$window','$rootScope', 'Monitor', function($window, $rootScope, Monitor) {
            var state = {running : false};
            $window.setInterval(function() {
                if(state.running === false) {
                    Monitor.monitor($rootScope, state);
                    state.running = false;
                }
            }, 2000);
        }]);

    if(typeof jasmine != 'undefined' && typeof beforeEach === 'function') {
        var $injector = angular.bootstrap(window, ['scope-aware']);
        var JasmineMatchersFactory = $injector.get('JasmineMatchersFactory');
        var matchers = JasmineMatchersFactory.create();
        beforeEach(function() {
            jasmine.addMatchers(matchers);
        });
    }
})(angular);<|endoftext|>


<commit_before>"use strict"

var Promise = require("bluebird")
var semver = require("semver")
var extend = require("extend")
var mkdirp = require("mkdirp")
var path = require("path")
var fs = require("fs")
var split = require("split")
var crypto = require("crypto")
var tar = require("tar")
var lzma = require("lzma-native")

var request = (function (request) {
  return function (url, cb) {
    return request({
      url: url,
      headers: { "User-Agent": "request iojs-bundler (" + moduleVersion + ")" }
    }, cb)
  }
})(require("request"))

var Installation = require("./Installation.js")

var moduleVersion = require(path.resolve(__dirname, "..", "package.json")).version

var Installer = module.exports = function (targetPath, versionSelector, opts) {
  this._targetPath = targetPath

  if (semver.validRange(versionSelector) === null) {
    throw new Error("Error validationg version selector: " + versionSelector)
  }

  this._opts = opts = extend({
    platform: process.platform,
    arch: process.arch
  }, opts)

  this._downloadCacheDir = new Promise(function (resolve, reject) {
    var cacheDir = path.resolve(__dirname, "..", "cache")
    mkdirp(cacheDir, function (err) {
      if (err) return reject(err)
      return resolve(cacheDir)
    })
  })

  this._version = new Promise(function (resolve, reject) {
    var indexJson = "https://iojs.org/dist/index.json"
    request(indexJson, function (err, res, body) {
      if (err) {
        return reject(err)
      }
      if (res.statusCode !== 200) {
        return reject(new Error(indexJson + ": Unexpected status code: " + res.statusCode))
      }
      if (res.headers['content-type'] !== "application/json") {
        return reject(new Error(indexJson + ": Unexpected Content-Type: " + res.headers['content-type']))
      }

      try { var index = JSON.parse(body) }
      catch (e) { return reject(e) }

      var versions = index.map(function (release) { return release.version.replace(/^v/, "") })
      var satisfyingVersion = semver.maxSatisfying(versions, versionSelector)
      if (satisfyingVersion === null) {
        return reject(new Error("No version satisfies semver range: " + versionSelector))
      }

      return resolve(satisfyingVersion)
    })
  })

  this._installerFileName = this._version.then(function (version) {
    return "iojs-v" + version + "-" + opts.platform + "-" + opts.arch + ".tar.gz"
  })

  this._installerFileUrl = Promise.join(this._version, this._installerFileName, function (version, installerFileName) {
    return "https://iojs.org/dist/v" + version + "/" + installerFileName
  })

  this._srcFileName = this._version.then(function (version) {
    return "iojs-v" + version + ".tar.xz"
  })

  this._srcFileUrl = Promise.join(this._version, this._srcFileName, function (version, srcFileName) {
    return "https://iojs.org/dist/v" + version + "/" + srcFileName
  })

  this._downloadCacheDirForVersion = Promise.join(this._version, this._downloadCacheDir, function (version, downloadCacheDir) {
    return new Promise(function (resolve, reject) {
      var cacheDir = path.resolve(downloadCacheDir, version)
      mkdirp(cacheDir, function (err) {
        if (err) return reject(err)
        return resolve(cacheDir)
      })
    })
  })

  this._shasums = Promise.join(this._downloadCacheDirForVersion, this._version, function (cacheDir, version) {
    return new Promise(function (resolve, reject) {
      var shasumsFileUrl = "https://iojs.org/dist/v" + version + "/SHASUMS256.txt"
      var cachedShasumFilePath = path.join(cacheDir, "SHASUM256.txt")
      fs.exists(cachedShasumFilePath, function (isCached) {
        if (isCached) return resolve(parseShasumFile(cachedShasumFilePath))
        request(shasumsFileUrl)
          .on("error", reject)
          .pipe(fs.createWriteStream(cachedShasumFilePath))
            .on("error", reject)
            .on("finish", function () { return resolve(parseShasumFile(cachedShasumFilePath)) })
      })
    })
  })

  this._installerFile = this._downloadAndCacheFile(this._installerFileUrl, this._installerFileName)

  this._srcFile = this._downloadAndCacheFile(this._srcFileUrl, this._srcFileName)

  this._srcDir = Promise.join(this._downloadCacheDirForVersion, this._srcFileName, this._srcFile, function (cacheDir, srcFileName, srcFilePath) {
    return new Promise(function (resolve, reject) {
      var srcDir = path.resolve(cacheDir, srcFileName.replace(/\.tar\.xz$/, ""))
      fs.exists(path.resolve(srcDir, "README.md"), function (isExtracted) {
        if (isExtracted) return resolve(srcDir)
        fs.createReadStream(srcFilePath)
          .on("error", reject)
          .pipe(lzma.createStream("autoDecoder"))
            .on("error", reject)
            .pipe(tar.Extract({ path: cacheDir }))
              .on("error", reject)
              .on("end", function () { return resolve(srcDir) })
      })
    })
  })
}

Installer.prototype._downloadAndCacheFile = function (fileUrl, fileName) {
  return Promise.join(
    fileUrl, fileName, this._downloadCacheDirForVersion, this._shasums,
    function(fileUrl, fileName, cacheDir, shasums) {
      return new Promise(function (resolve, reject) {
        var cachedFilePath = path.join(cacheDir, fileName)
        var expectedShasum = shasums[fileName]
        if (expectedShasum === undefined) return reject(new Error("Could not find installer file in shasum list!"))
        fs.exists(cachedFilePath, function (isCached) {
          if (isCached) return resolve(validateShasum(cachedFilePath, expectedShasum))
          request(fileUrl)
            .on("error", reject)
            .pipe(fs.createWriteStream(cachedFilePath))
              .on("error", reject)
              .on("finish", function () { return resolve(validateShasum(cachedFilePath, expectedShasum)) })
        })
      })
    }
  )
}

Installer.prototype.install = function (installPath, cb) {
  Promise.join(this._version, this._installerFile, this._srcDir, function (version, installerFile, srcDir) {
    var installation = new Installation(version)
    return cb(null, installation)
  })
  .then(null, function (err) {
    return cb(err)
  })
}

function parseShasumFile (path) {
  return new Promise(function (resolve, reject) {
    var shasums = {}
    fs.createReadStream(path)
      .on("error", reject)
      .pipe(split())
        .on("error", reject)
        .on("data", function (line) {
          var parts = line.match(/^(.+?)\s+(.+?)\s*$/)
          if (parts) shasums[parts[2]] = parts[1]
        })
        .on("end", function () {
          return resolve(shasums)
        })
  })
}

function validateShasum (path, expectedShasum) {
  return new Promise(function (resolve, reject) {
    var hash = crypto.createHash("sha256")
    fs.createReadStream(path)
      .on("error", reject)
      .pipe(hash)
        .on("error", reject)
        .on("finish", function () {
          var shasum = hash.read().toString("hex")
          if (shasum === expectedShasum) {
            return resolve(path)
          }
          else {
            return reject(new Error(path + ": expected sha256 " + expectedShasum + " but got " + shasum))
          }
        })
  })
}
<commit_msg>Extract iojs binary distribution file to cache dir<commit_after>"use strict"

var Promise = require("bluebird")
var semver = require("semver")
var extend = require("extend")
var mkdirp = require("mkdirp")
var path = require("path")
var fs = require("fs")
var split = require("split")
var crypto = require("crypto")
var tar = require("tar")
var lzma = require("lzma-native")
var zlib = require("zlib")

var request = (function (request) {
  return function (url, cb) {
    return request({
      url: url,
      headers: { "User-Agent": "request iojs-bundler (" + moduleVersion + ")" }
    }, cb)
  }
})(require("request"))

var Installation = require("./Installation.js")

var moduleVersion = require(path.resolve(__dirname, "..", "package.json")).version

var Installer = module.exports = function (targetPath, versionSelector, opts) {
  this._targetPath = targetPath

  if (semver.validRange(versionSelector) === null) {
    throw new Error("Error validationg version selector: " + versionSelector)
  }

  this._opts = opts = extend({
    platform: process.platform,
    arch: process.arch
  }, opts)

  this._downloadCacheDir = new Promise(function (resolve, reject) {
    var cacheDir = path.resolve(__dirname, "..", "cache")
    mkdirp(cacheDir, function (err) {
      if (err) return reject(err)
      return resolve(cacheDir)
    })
  })

  this._version = new Promise(function (resolve, reject) {
    var indexJson = "https://iojs.org/dist/index.json"
    request(indexJson, function (err, res, body) {
      if (err) {
        return reject(err)
      }
      if (res.statusCode !== 200) {
        return reject(new Error(indexJson + ": Unexpected status code: " + res.statusCode))
      }
      if (res.headers['content-type'] !== "application/json") {
        return reject(new Error(indexJson + ": Unexpected Content-Type: " + res.headers['content-type']))
      }

      try { var index = JSON.parse(body) }
      catch (e) { return reject(e) }

      var versions = index.map(function (release) { return release.version.replace(/^v/, "") })
      var satisfyingVersion = semver.maxSatisfying(versions, versionSelector)
      if (satisfyingVersion === null) {
        return reject(new Error("No version satisfies semver range: " + versionSelector))
      }

      return resolve(satisfyingVersion)
    })
  })

  this._installerFileName = this._version.then(function (version) {
    return "iojs-v" + version + "-" + opts.platform + "-" + opts.arch + ".tar.gz"
  })

  this._installerFileUrl = Promise.join(this._version, this._installerFileName, function (version, installerFileName) {
    return "https://iojs.org/dist/v" + version + "/" + installerFileName
  })

  this._srcFileName = this._version.then(function (version) {
    return "iojs-v" + version + ".tar.xz"
  })

  this._srcFileUrl = Promise.join(this._version, this._srcFileName, function (version, srcFileName) {
    return "https://iojs.org/dist/v" + version + "/" + srcFileName
  })

  this._downloadCacheDirForVersion = Promise.join(this._version, this._downloadCacheDir, function (version, downloadCacheDir) {
    return new Promise(function (resolve, reject) {
      var cacheDir = path.resolve(downloadCacheDir, version)
      mkdirp(cacheDir, function (err) {
        if (err) return reject(err)
        return resolve(cacheDir)
      })
    })
  })

  this._shasums = Promise.join(this._downloadCacheDirForVersion, this._version, function (cacheDir, version) {
    return new Promise(function (resolve, reject) {
      var shasumsFileUrl = "https://iojs.org/dist/v" + version + "/SHASUMS256.txt"
      var cachedShasumFilePath = path.join(cacheDir, "SHASUM256.txt")
      fs.exists(cachedShasumFilePath, function (isCached) {
        if (isCached) return resolve(parseShasumFile(cachedShasumFilePath))
        request(shasumsFileUrl)
          .on("error", reject)
          .pipe(fs.createWriteStream(cachedShasumFilePath))
            .on("error", reject)
            .on("finish", function () { return resolve(parseShasumFile(cachedShasumFilePath)) })
      })
    })
  })

  this._installerFile = this._downloadAndCacheFile(this._installerFileUrl, this._installerFileName)

  this._srcFile = this._downloadAndCacheFile(this._srcFileUrl, this._srcFileName)

  this._srcDir = Promise.join(this._downloadCacheDirForVersion, this._srcFileName, this._srcFile, function (cacheDir, srcFileName, srcFilePath) {
    return new Promise(function (resolve, reject) {
      var srcDir = path.resolve(cacheDir, srcFileName.replace(/\.tar\.xz$/, ""))
      fs.exists(path.resolve(srcDir, "README.md"), function (isExtracted) {
        if (isExtracted) return resolve(srcDir)
        fs.createReadStream(srcFilePath)
          .on("error", reject)
          .pipe(lzma.createStream("autoDecoder"))
            .on("error", reject)
            .pipe(tar.Extract({ path: cacheDir }))
              .on("error", reject)
              .on("end", function () { return resolve(srcDir) })
      })
    })
  })

  this._extractedInstallDir = Promise.join(this._installerFileName, this._downloadCacheDirForVersion, this._installerFile, function (installerFileName, cacheDir, installerFilePath) {
    return new Promise(function (resolve, reject) {
      var installDirPath = path.resolve(cacheDir, installerFileName)
      fs.exists(path.resolve(installDirPath, "bin", "iojs"), function (isExtracted) {
        if (isExtracted) return resolve(installDirPath)
        fs.createReadStream(installerFilePath)
          .on("error", reject)
          .pipe(zlib.createGunzip())
            .on("error", reject)
            .pipe(tar.Extract({ path: cacheDir }))
              .on("error", reject)
              .on("end", function () { return resolve(installDirPath) })
      })
    })
  })
}

Installer.prototype._downloadAndCacheFile = function (fileUrl, fileName) {
  return Promise.join(
    fileUrl, fileName, this._downloadCacheDirForVersion, this._shasums,
    function(fileUrl, fileName, cacheDir, shasums) {
      return new Promise(function (resolve, reject) {
        var cachedFilePath = path.join(cacheDir, fileName)
        var expectedShasum = shasums[fileName]
        if (expectedShasum === undefined) return reject(new Error("Could not find installer file in shasum list!"))
        fs.exists(cachedFilePath, function (isCached) {
          if (isCached) return resolve(validateShasum(cachedFilePath, expectedShasum))
          request(fileUrl)
            .on("error", reject)
            .pipe(fs.createWriteStream(cachedFilePath))
              .on("error", reject)
              .on("finish", function () { return resolve(validateShasum(cachedFilePath, expectedShasum)) })
        })
      })
    }
  )
}

Installer.prototype.install = function (installPath, cb) {
  Promise.join(this._version, this._srcDir, this._extractedInstallDir, function (version, srcDir, extractedInstallDir) {
    var installation = new Installation(version)
    return cb(null, installation)
  })
  .then(null, function (err) {
    return cb(err)
  })
}

function parseShasumFile (path) {
  return new Promise(function (resolve, reject) {
    var shasums = {}
    fs.createReadStream(path)
      .on("error", reject)
      .pipe(split())
        .on("error", reject)
        .on("data", function (line) {
          var parts = line.match(/^(.+?)\s+(.+?)\s*$/)
          if (parts) shasums[parts[2]] = parts[1]
        })
        .on("end", function () {
          return resolve(shasums)
        })
  })
}

function validateShasum (path, expectedShasum) {
  return new Promise(function (resolve, reject) {
    var hash = crypto.createHash("sha256")
    fs.createReadStream(path)
      .on("error", reject)
      .pipe(hash)
        .on("error", reject)
        .on("finish", function () {
          var shasum = hash.read().toString("hex")
          if (shasum === expectedShasum) {
            return resolve(path)
          }
          else {
            return reject(new Error(path + ": expected sha256 " + expectedShasum + " but got " + shasum))
          }
        })
  })
}
<|endoftext|>


<commit_before>import {EventEmitter} from "events"
import TailFollow from "tail-follow"
import {resolve} from "path"

export default class LiveIndex extends EventEmitter {
  constructor ({pathToWatch, indexer}) {
    super()

    this._watchPaths = []
    this._indexers = []
    this._tails = new Map()
    this._files = new Map()
    this._index = new Map()

    if (pathToWatch) {
        this.addPathToWatch(pathToWatch)
    }

    if (indexer) {
      this.addIndexer(indexer)
    }

    if (pathToWatch && indexer) {
      this.watch()
    }
  }

  addPathToWatch (path) {
    this._watchPaths.push(resolve(path))
  }

  addIndexer (evaluator) {
    this._indexers.push(evaluator)
  }

  watch () {
    this._watchPaths.forEach(path => {
      const file = new File(path)
      this._files.set(path, file)

      const tail = new TailFollow(path, {
        surviveRotation: true,
        objectMode: true
      })
      this._tails.set(path, tail)

      tail
        .on("data", chunk => {
          const pos = tail.positionForChunk(chunk)
          this._evaluateChunk(path, pos, chunk)
        })
        .on("rename", (oldPath, newPath) => {
          const renamedFile = this._files.get(oldPath)
          renamedFile.path = newPath
          this._files.set(newPath, renamedFile)
          this._files.set(oldPath, new File(oldPath))
        })
    })
  }

  _evaluateChunk (path, pos, chunk) {
    this._indexers.forEach(indexer => {
      const addIndex = (identifier, positionInChunk) => {
        this.insert(identifier, path, pos + positionInChunk)
      }
      indexer(chunk, addIndex)
    })
  }

  insert (identifier, filePath, position) {
    const file = this._files.get(filePath)
    this._index.set(identifier, {file, position})
    this.emit("insert", identifier)
  }

  fileAndPositionForIdentifier (identifier) {
    const result = this._index.get(identifier)
    return {
      position: result.position,
      file: result.file.path
    }
  }
}

class File {
  constructor (path) {
    this.path = path
  }
}
<commit_msg>Return undefined when identifier not in index<commit_after>import {EventEmitter} from "events"
import TailFollow from "tail-follow"
import {resolve} from "path"

export default class LiveIndex extends EventEmitter {
  constructor ({pathToWatch, indexer}) {
    super()

    this._watchPaths = []
    this._indexers = []
    this._tails = new Map()
    this._files = new Map()
    this._index = new Map()

    if (pathToWatch) {
        this.addPathToWatch(pathToWatch)
    }

    if (indexer) {
      this.addIndexer(indexer)
    }

    if (pathToWatch && indexer) {
      this.watch()
    }
  }

  addPathToWatch (path) {
    this._watchPaths.push(resolve(path))
  }

  addIndexer (evaluator) {
    this._indexers.push(evaluator)
  }

  watch () {
    this._watchPaths.forEach(path => {
      const file = new File(path)
      this._files.set(path, file)

      const tail = new TailFollow(path, {
        surviveRotation: true,
        objectMode: true
      })
      this._tails.set(path, tail)

      tail
        .on("data", chunk => {
          const pos = tail.positionForChunk(chunk)
          this._evaluateChunk(path, pos, chunk)
        })
        .on("rename", (oldPath, newPath) => {
          const renamedFile = this._files.get(oldPath)
          renamedFile.path = newPath
          this._files.set(newPath, renamedFile)
          this._files.set(oldPath, new File(oldPath))
        })
    })
  }

  _evaluateChunk (path, pos, chunk) {
    this._indexers.forEach(indexer => {
      const addIndex = (identifier, positionInChunk) => {
        this.insert(identifier, path, pos + positionInChunk)
      }
      indexer(chunk, addIndex)
    })
  }

  insert (identifier, filePath, position) {
    const file = this._files.get(filePath)
    this._index.set(identifier, {file, position})
    this.emit("insert", identifier)
  }

  fileAndPositionForIdentifier (identifier) {
    const result = this._index.get(identifier)
    if (result === undefined) { return undefined }
    return {
      position: result.position,
      file: result.file.path
    }
  }
}

class File {
  constructor (path) {
    this.path = path
  }
}
<|endoftext|>