<commit_before>var through = require('through'),
	fs = require('fs'),
	through2 = require('through2'),
  path = require('path'),
  watchify = require('watchify'),
  chalk = require('chalk'),
  gutil = require('gulp-util'),
	PluginError = gutil.PluginError,
	File = gutil.File,
	_ = require('underscore'),
	source = require('vinyl-source-stream'),
	gulp = require('gulp'),
	streamify = require('gulp-streamify'),
	mapify = require('mapify'),
	compiles = 0,
	endStreamFn,
	lastExecTime,
	lastExecData;

// Log with a prefix
function log() {
	var args = Array.prototype.slice.call(arguments);
	var prefix = [chalk.magenta('[gulp-browserify]')];
	args[0] = prefix + ' ' + args[0];

	return gutil.log.apply(this,args);
}

// Keep adding files until there are none left
function addFiles(file){
	if (file.isStream()) {
		return this.emit('error', new PluginError(
			'gulp-browserify',
			'Streaming not supported'
		));
	}

	this._data = this._data || {};

	if (!this._data.firstFile) this._data.firstFile = file;

	if(!_.has(this._data,'files')) this._data.files = [];

	this._data.files.push(file.path);
}

function endStream(files) {
    files = this._data.files;
	if (files.length === 0) return this.emit('end');

	return endStreamFn.apply(this);
}

// Function that is called once endStream is called
function waitForStream(callback) {
	endStreamFn = callback;
}

// Create a single Vinyl FS stream.
function createSourceStream(filename,opts) {
	var ins = through2();
	var out = false;

	if (filename) {
		filename = path.resolve(filename);
	}

	var file = new File(filename ? {
		path: filename,
		contents: ins
	} : {
		contents: ins
	});

	return through2({
		objectMode: true
	}, function(chunk, enc, next) {
	if (!out) {
		this.push(file);
		out = true;
	}

	ins.push(chunk);
	next();
	}, function() {
		// Optionally add a "footer" to the output.
		if(typeof(opts.footer) !== 'undefined') {
			ins.push(opts.footer);
		}
		ins.push(null);
		this.push(null);
	});
}

// Build function, called from __main
function build(opts) {
	// Stream data
	var stream = this;
	var data = this._data;
	var cwd = data.firstFile.cwd;
	var root = path.dirname(module.parent.filename);

	if (!opts) opts = {};

	// Accept single string format
	if(typeof(opts) !== 'object') {
		opts = {};
		opts.filename = filename;
	}

	// Default options..
	defaultFilename = 'bundle.js';

	var _defaults = {
		filename: defaultFilename,
		aliasMappings: {
			pathSeperator: '/',
			entries: []
		},
		requireAll: true,
		verbose: false,
		watch: true,
		noBowerParse: true
	};

	_.defaults(opts, _defaults);
	_.defaults(opts.aliasMappings,_defaults.aliasMappings);

	var filename = opts.filename;

	var funcArgs = [
		'maskFilenames',
		'requireAll',
		'aliasMappings',
		'filename',
		'watch',
		'footer',
		'parseBower'
	];

	// Get an option list for browserify
	var browserifyOpts = {};
	Object.keys(opts).forEach(function(key) {
		value = opts[key];

		if(!_.contains(funcArgs,key)) {
			browserifyOpts[key] = value;
		}
	});

	// Default browserify options
	browserifyOpts = _.defaults(browserifyOpts, {noParse: []});

	// Don't parse any bower_components files
	if(opts.noBowerParse === true) {
		var bower_path = path.resolve(root,'bower_components');
		var dirs = fs.readdirSync(bower_path);
		dirs.forEach(function(dir) {
			if(dir !== '.DS_Store') {
				var pkg_path = path.join(bower_path,dir);

				if(fs.existsSync(path.join(pkg_path,'bower.json'))) {
					var main_paths = require(path.join(pkg_path,'bower.json')).main;
					if(!_.isArray(main_paths)) {
						main_paths = [main_paths];
					}

					main_paths.forEach(function(main_path) {
						var abs_path = path.resolve(pkg_path,main_path);
						browserifyOpts.noParse.push(abs_path);
						browserifyOpts.noParse.push(path.relative(root,abs_path));
						browserifyOpts.noParse.push(path.relative(opts.basedir,abs_path));
					});
				}
			}
		});
	}

	var bundler = watchify(browserifyOpts);

	function newError(e) {
		throw e;
	}

	// Bubble up errors to stream
	bundler.on('error', newError);

	// Require each file that was found in the stream
	data.files.forEach(function(file,index) {
		bundler.add(file);
	});

	// Expose files through mapify
	var aliasEntries = opts.aliasMappings.entries;
	if(aliasEntries.length && _.values(_.first(aliasEntries)).length) {
		bundler.require = _.wrap(bundler.require, function(func,file,opts) {
			stream.emit('require', file, opts);
			func.call(this,file,opts);
		});

		bundler.plugin(mapify,opts.aliasMappings);
	}

	// Compile new bundle.js every time one of the files changes
	function rebundle(ids) {
		stream.emit('prebundle', bundler);

		compiles++;

		if(opts && opts.verbose && lastExecTime) {
			var lastExec = (Date.now() - lastExecTime);

			if(lastExec > 0) {
				log('time since last execution: ' +
					chalk.cyan(lastExec + 'ms'));
			}
		}
		lastExecTime = Date.now();

		var start_time = Date.now();

		var bundle = bundler.bundle(opts);

		// Use a vinyl source stream to convert the whole bundle to
		// one compiled file.
		// TODO: Should be able to use vinyl-source-stream for this
		var browserifystream = bundle.pipe(createSourceStream(filename,opts));

		// Once the bundle is complete, fire a callback so that gulp knows
		// when to proceed to the next step.
		browserifystream.on('data',function(data) {
			stream.emit('data', data);
			stream.emit('postbundle', bundler);

			// Log execution time
			var end_time = Date.now();
			if(end_time-start_time > 0) {
				var exec_time = chalk.cyan((end_time-start_time) + 'ms');
				log('compiled in ' + exec_time);
			}

			// If compiles is >= 1, and opts.watch is false, stop watching
			if(compiles >= 1 && opts.watch === false) {
				console.log('ending');
				stream.emit('end');
				bundler.close();
			}
		});

		return bundle;
	}

	bundler.on('update', rebundle);

	return rebundle();
}

function __main(opts) {
	// Wait till all the files are there
	waitForStream(function() {
		build.call(this,opts);
	});

	return through(addFiles, endStream);
}

module.exports = __main;<commit_msg>remove console log<commit_after>var through = require('through'),
	fs = require('fs'),
	through2 = require('through2'),
  path = require('path'),
  watchify = require('watchify'),
  chalk = require('chalk'),
  gutil = require('gulp-util'),
	PluginError = gutil.PluginError,
	File = gutil.File,
	_ = require('underscore'),
	source = require('vinyl-source-stream'),
	gulp = require('gulp'),
	streamify = require('gulp-streamify'),
	mapify = require('mapify'),
	compiles = 0,
	endStreamFn,
	lastExecTime,
	lastExecData;

// Log with a prefix
function log() {
	var args = Array.prototype.slice.call(arguments);
	var prefix = [chalk.magenta('[gulp-browserify]')];
	args[0] = prefix + ' ' + args[0];

	return gutil.log.apply(this,args);
}

// Keep adding files until there are none left
function addFiles(file){
	if (file.isStream()) {
		return this.emit('error', new PluginError(
			'gulp-browserify',
			'Streaming not supported'
		));
	}

	this._data = this._data || {};

	if (!this._data.firstFile) this._data.firstFile = file;

	if(!_.has(this._data,'files')) this._data.files = [];

	this._data.files.push(file.path);
}

function endStream(files) {
    files = this._data.files;
	if (files.length === 0) return this.emit('end');

	return endStreamFn.apply(this);
}

// Function that is called once endStream is called
function waitForStream(callback) {
	endStreamFn = callback;
}

// Create a single Vinyl FS stream.
function createSourceStream(filename,opts) {
	var ins = through2();
	var out = false;

	if (filename) {
		filename = path.resolve(filename);
	}

	var file = new File(filename ? {
		path: filename,
		contents: ins
	} : {
		contents: ins
	});

	return through2({
		objectMode: true
	}, function(chunk, enc, next) {
	if (!out) {
		this.push(file);
		out = true;
	}

	ins.push(chunk);
	next();
	}, function() {
		// Optionally add a "footer" to the output.
		if(typeof(opts.footer) !== 'undefined') {
			ins.push(opts.footer);
		}
		ins.push(null);
		this.push(null);
	});
}

// Build function, called from __main
function build(opts) {
	// Stream data
	var stream = this;
	var data = this._data;
	var cwd = data.firstFile.cwd;
	var root = path.dirname(module.parent.filename);

	if (!opts) opts = {};

	// Accept single string format
	if(typeof(opts) !== 'object') {
		opts = {};
		opts.filename = filename;
	}

	// Default options..
	defaultFilename = 'bundle.js';

	var _defaults = {
		filename: defaultFilename,
		aliasMappings: {
			pathSeperator: '/',
			entries: []
		},
		requireAll: true,
		verbose: false,
		watch: true,
		noBowerParse: true
	};

	_.defaults(opts, _defaults);
	_.defaults(opts.aliasMappings,_defaults.aliasMappings);

	var filename = opts.filename;

	var funcArgs = [
		'maskFilenames',
		'requireAll',
		'aliasMappings',
		'filename',
		'watch',
		'footer',
		'parseBower'
	];

	// Get an option list for browserify
	var browserifyOpts = {};
	Object.keys(opts).forEach(function(key) {
		value = opts[key];

		if(!_.contains(funcArgs,key)) {
			browserifyOpts[key] = value;
		}
	});

	// Default browserify options
	browserifyOpts = _.defaults(browserifyOpts, {noParse: []});

	// Don't parse any bower_components files
	if(opts.noBowerParse === true) {
		var bower_path = path.resolve(root,'bower_components');
		var dirs = fs.readdirSync(bower_path);
		dirs.forEach(function(dir) {
			if(dir !== '.DS_Store') {
				var pkg_path = path.join(bower_path,dir);

				if(fs.existsSync(path.join(pkg_path,'bower.json'))) {
					var main_paths = require(path.join(pkg_path,'bower.json')).main;
					if(!_.isArray(main_paths)) {
						main_paths = [main_paths];
					}

					main_paths.forEach(function(main_path) {
						var abs_path = path.resolve(pkg_path,main_path);
						browserifyOpts.noParse.push(abs_path);
						browserifyOpts.noParse.push(path.relative(root,abs_path));
						browserifyOpts.noParse.push(path.relative(opts.basedir,abs_path));
					});
				}
			}
		});
	}

	var bundler = watchify(browserifyOpts);

	function newError(e) {
		throw e;
	}

	// Bubble up errors to stream
	bundler.on('error', newError);

	// Require each file that was found in the stream
	data.files.forEach(function(file,index) {
		bundler.add(file);
	});

	// Expose files through mapify
	var aliasEntries = opts.aliasMappings.entries;
	if(aliasEntries.length && _.values(_.first(aliasEntries)).length) {
		bundler.require = _.wrap(bundler.require, function(func,file,opts) {
			stream.emit('require', file, opts);
			func.call(this,file,opts);
		});

		bundler.plugin(mapify,opts.aliasMappings);
	}

	// Compile new bundle.js every time one of the files changes
	function rebundle(ids) {
		stream.emit('prebundle', bundler);

		compiles++;

		if(opts && opts.verbose && lastExecTime) {
			var lastExec = (Date.now() - lastExecTime);

			if(lastExec > 0) {
				log('time since last execution: ' +
					chalk.cyan(lastExec + 'ms'));
			}
		}
		lastExecTime = Date.now();

		var start_time = Date.now();

		var bundle = bundler.bundle(opts);

		// Use a vinyl source stream to convert the whole bundle to
		// one compiled file.
		// TODO: Should be able to use vinyl-source-stream for this
		var browserifystream = bundle.pipe(createSourceStream(filename,opts));

		// Once the bundle is complete, fire a callback so that gulp knows
		// when to proceed to the next step.
		browserifystream.on('data',function(data) {
			stream.emit('data', data);
			stream.emit('postbundle', bundler);

			// Log execution time
			var end_time = Date.now();
			if(end_time-start_time > 0) {
				var exec_time = chalk.cyan((end_time-start_time) + 'ms');
				log('compiled in ' + exec_time);
			}

			// If compiles is >= 1, and opts.watch is false, stop watching
			if(compiles >= 1 && opts.watch === false) {
				stream.emit('end');
				bundler.close();
			}
		});

		return bundle;
	}

	bundler.on('update', rebundle);

	return rebundle();
}

function __main(opts) {
	// Wait till all the files are there
	waitForStream(function() {
		build.call(this,opts);
	});

	return through(addFiles, endStream);
}

module.exports = __main;<|endoftext|>


<commit_before>var express = require('express');
var app = express();

app.set('port', (process.env.PORT || 5000));

app.get('/', function (req, res) {

	console.log('--------------------------------GET');
	console.log('base URL', req.baseUrl);
	console.log('authorization', req.get("authorization"));
	console.log('x-forwarded-proto', req.get('x-forwarded-proto'));
	console.log('x-forwarded-for', req.get('x-forwarded-for'));
	console.log('x-forwarded-port', req.get('x-forwarded-port'));
	console.log('params', req.params);
	console.log('query', req.query);
	console.log('body', req.body);
	console.log('--------------------------------');

	res.send('OK');
});

app.post('/', function (req, res) {

	console.log('--------------------------------POST');
	console.log('base URL', req.baseUrl);
	console.log('authorization', req.get("authorization"));
	console.log('x-forwarded-proto', req.get('x-forwarded-proto'));
	console.log('x-forwarded-for', req.get('x-forwarded-for'));
	console.log('x-forwarded-port', req.get('x-forwarded-port'));
	console.log('params', req.params);
	console.log('query', req.query);
	console.log('body', req.body);
	console.log('--------------------------------');

	res.send('OK');
});

app.put('/', function (req, res) {

	console.log('--------------------------------PUT');
	console.log('base URL', req.baseUrl);
	console.log('authorization', req.get("authorization"));
	console.log('x-forwarded-proto', req.get('x-forwarded-proto'));
	console.log('x-forwarded-for', req.get('x-forwarded-for'));
	console.log('x-forwarded-port', req.get('x-forwarded-port'));
	console.log('params', req.params);
	console.log('query', req.query);
	console.log('body', req.body);
	console.log('--------------------------------');

	res.send('OK');
});

// Heroku
app.listen(app.get('port'), function () {
	console.log('Node app is running on port', app.get('port'));
});<commit_msg>logging entire request for post<commit_after>var express = require('express');
var app = express();

app.set('port', (process.env.PORT || 5000));

app.get('/', function (req, res) {

	console.log('--------------------------------GET');
	console.log('base URL', req.baseUrl);
	console.log('authorization', req.get("authorization"));
	console.log('x-forwarded-proto', req.get('x-forwarded-proto'));
	console.log('x-forwarded-for', req.get('x-forwarded-for'));
	console.log('x-forwarded-port', req.get('x-forwarded-port'));
	console.log('params', req.params);
	console.log('query', req.query);
	console.log('body', req.body);
	console.log('--------------------------------');

	res.send('OK');
});

app.post('/', function (req, res) {

	console.log('--------------------------------POST');
	console.log('base URL', req.baseUrl);
	console.log('authorization', req.get("authorization"));
	console.log('x-forwarded-proto', req.get('x-forwarded-proto'));
	console.log('x-forwarded-for', req.get('x-forwarded-for'));
	console.log('x-forwarded-port', req.get('x-forwarded-port'));
	console.log('params', req.params);
	console.log('query', req.query);
	console.log('body', req.body);
	console.log(req);
	console.log('--------------------------------');

	res.send('OK');
});

app.put('/', function (req, res) {

	console.log('--------------------------------PUT');
	console.log('base URL', req.baseUrl);
	console.log('authorization', req.get("authorization"));
	console.log('x-forwarded-proto', req.get('x-forwarded-proto'));
	console.log('x-forwarded-for', req.get('x-forwarded-for'));
	console.log('x-forwarded-port', req.get('x-forwarded-port'));
	console.log('params', req.params);
	console.log('query', req.query);
	console.log('body', req.body);
	console.log('--------------------------------');

	res.send('OK');
});

// Heroku
app.listen(app.get('port'), function () {
	console.log('Node app is running on port', app.get('port'));
});<|endoftext|>


<commit_before>/**
 * Created by gillbeits on 01/04/15.
 */

var
  HOST        = 'http://fontello.com',

  needle      = require('needle'),
  through2    = require('through2'),
  unzip       = require('unzip'),
  path        = require('path'),
  $           = require('gulp-util'),

  PluginError = $.PluginError
  ;

const PLUGIN_NAME = 'gulp-fontello';

function fontello () {
  "use strict";

  return through2.obj(function (file, enc, callback) {

    if (!file.isBuffer() || !file.path) {
      throw new PluginError(PLUGIN_NAME, "No config file for Fontello");
    }
    var self = this;

    var stream = through2.obj(function (file) {
      if (!file.toString()) {
        throw new PluginError(PLUGIN_NAME, "No session at Fontello for zip archive");
      }

      var zipFile;
      zipFile = needle.get(HOST + "/" + file.toString() + "/get", function(error) {
        if (error) {
          throw error;
        }
      });

      zipFile
        .pipe(unzip.Parse())
        .on('entry', function (entry) {
          var dirName, fileName, pathName, type, _ref, chunks = [];
          pathName = entry.path, type = entry.type;

          entry.pipe(through2.obj(function (chunk, enc, cb) {
            chunks.push(chunk);
            cb();
          }, function (cb) {
            if(chunks.length > 0){
              dirName = (_ref = path.dirname(pathName).match(/\/([^\/]*)$/)) != null ? _ref[1] : void 0;
              fileName = path.basename(pathName);
              entry.path = fileName;

              switch (dirName) {
                case 'css':
                case 'font':
                  var file = new $.File({
                    cwd : "./",
                    path : entry.path,
                    contents: Buffer.concat(chunks)
                  });
                  self.push(file);
                  break;
                default:
                  return entry.autodrain();
              }
            }
            cb()
          }))
        }).on('close', function(){
          callback()
        });
    });

    needle.post(HOST, {
      config: {
        file: file.path,
        content_type: 'application/json'
      }
    }, { multipart: true }).pipe(stream);
  });
}

module.exports = fontello;<commit_msg>outputting all files from the zip in the original file structure<commit_after>/**
 * Created by gillbeits on 01/04/15.
 */

var
  HOST        = 'http://fontello.com',

  needle      = require('needle'),
  through2    = require('through2'),
  unzip       = require('unzip'),
  path        = require('path'),
  $           = require('gulp-util'),

  PluginError = $.PluginError
  ;

const PLUGIN_NAME = 'gulp-fontello';

function fontello () {
  "use strict";

  return through2.obj(function (file, enc, callback) {

    if (!file.isBuffer() || !file.path) {
      throw new PluginError(PLUGIN_NAME, "No config file for Fontello");
    }
    var self = this;

    var stream = through2.obj(function (file) {
      if (!file.toString()) {
        throw new PluginError(PLUGIN_NAME, "No session at Fontello for zip archive");
      }

      var zipFile;
      zipFile = needle.get(HOST + "/" + file.toString() + "/get", function(error) {
        if (error) {
          throw error;
        }
      });

      zipFile
        .pipe(unzip.Parse())
        .on('entry', function (entry) {
          var dirName, fileName, pathName, type, _ref, chunks = [];
          pathName = entry.path, type = entry.type;

          entry.pipe(through2.obj(function (chunk, enc, cb) {
            chunks.push(chunk);
            cb();
          }, function (cb) {
            if(chunks.length > 0){
              dirName = (_ref = path.dirname(pathName).match(/\/([^\/]*)$/)) != null ? _ref[1] : void 0;
              fileName = path.basename(pathName);
              entry.path = fileName;

              var file = new $.File({
                cwd : "./",
                path : (dirName ? (dirName + '/') : '')+ entry.path,
                contents: Buffer.concat(chunks)
              });
              self.push(file);
            }
            cb()
          }))
        }).on('close', function(){
          callback()
        });
    });

    needle.post(HOST, {
      config: {
        file: file.path,
        content_type: 'application/json'
      }
    }, { multipart: true }).pipe(stream);
  });
}

module.exports = fontello;<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { Text } from 'react-native';

const delayShape = PropTypes.shape({
  at: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(RegExp)
  ]),
  delay: PropTypes.number
});

const propTypes = {
  children: PropTypes.string.isRequired,
  typing: PropTypes.oneOf([-1, 0, 1]),
  maxDelay: PropTypes.number,
  minDelay: PropTypes.number,
  initialDelay: PropTypes.number,
  delayMap: PropTypes.arrayOf(delayShape),
  onTyped: PropTypes.func,
  onTypingEnd: PropTypes.func
};

const MAX_DELAY = 100;

const defaultProps = {
  initialDelay: MAX_DELAY * 2,
  maxDelay: MAX_DELAY,
  minDelay: MAX_DELAY / 5,
  typing: 0
};

function isEqual(current, next) {
  return current === next;
}

class TypeWriter extends Component {
  constructor(props) {
    super(props);

    this.state = { visibleChars: 0 };

    this.setNextState = this.setNextState.bind(this);
  }

  componentDidMount() {
    this.start();
  }

  componentWillReceiveProps(nextProps) {
    const active = this.props.typing;
    const next = nextProps.typing;

    if (next === 0) {
      this.clearTimeout();
    } else if (!isEqual(active, next)) {
      this.setNextState(next);
    } else if (!isEqual(nextProps.children, this.props.children)) {
      this.setState({ visibleChars: 0 });
      this.start();
    }
  }

  shouldComponentUpdate(nextProps, nextState) {
    return (
      !isEqual(this.state.visibleChars, nextState.visibleChars) ||
      !isEqual(this.props.children, nextProps.children)
    );
  }

  componentDidUpdate(prevProps, prevState) {
    const {
      children,
      delayMap,
      onTyped,
      onTypingEnd
    } = this.props;
    const { visibleChars } = prevState;
    const currentToken = children[visibleChars];
    const nextToken = children[this.state.visibleChars];

    if (currentToken && onTyped) {
      onTyped(currentToken, visibleChars);
    }

    if (nextToken) {
      let timeout = this.getRandomTimeout();

      if (delayMap) {
        delayMap.forEach(({ at, delay }) => {
          if (isEqual(at, visibleChars) || currentToken.match(at)) {
            timeout += delay;
          }
        });
      }

      this.start(timeout);
    } else if (onTypingEnd) {
      onTypingEnd();
    }
  }

  componentWillUnmount() {
    this.clearTimeout();
  }

  setNextState(typing = this.props.typing) {
    this.setState({ visibleChars: this.state.visibleChars + typing });
  }

  getRandomTimeout() {
    const { maxDelay, minDelay } = this.props;

    return Math.round(Math.random() * (maxDelay - minDelay) + minDelay);
  }

  clearTimeout() {
    if (this.timeoutId) {
      clearTimeout(this.timeoutId);
    }
  }

  start(timeout = this.props.initialDelay) {
    this.clearTimeout();
    this.timeoutId = setTimeout(this.setNextState, timeout);
  }

  render() {
    const { children, ...props } = this.props;
    const { visibleChars } = this.state;
    const { fixed } = this.props;

    const visibleString = children.slice(0, visibleChars)

    let components = [(
      <Text
        { ...props }
        key="visible-string">
        {visibleString}
      </Text>
    )];
    if (fixed) {
      const invisibleString = children.slice(visibleChars)
      props.style = {
        ...props.style,
        opacity: 0,
      }
      components.push(
        <Text
          { ...props }
          key="invisible-string">
          {invisibleString}
        </Text>
      );
    }
    return (
      <Text>
        {components}
      </Text>
    );
  }
}

TypeWriter.propTypes = propTypes;
TypeWriter.defaultProps = defaultProps;

export default TypeWriter
<commit_msg>Add default value<commit_after>import React, { Component, PropTypes } from 'react';
import { Text } from 'react-native';

const delayShape = PropTypes.shape({
  at: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(RegExp)
  ]),
  delay: PropTypes.number
});

const propTypes = {
  children: PropTypes.string.isRequired,
  typing: PropTypes.oneOf([-1, 0, 1]),
  maxDelay: PropTypes.number,
  minDelay: PropTypes.number,
  initialDelay: PropTypes.number,
  delayMap: PropTypes.arrayOf(delayShape),
  onTyped: PropTypes.func,
  onTypingEnd: PropTypes.func
};

const MAX_DELAY = 100;

const defaultProps = {
  initialDelay: MAX_DELAY * 2,
  maxDelay: MAX_DELAY,
  minDelay: MAX_DELAY / 5,
  typing: 0,
  fixed: false,
};

function isEqual(current, next) {
  return current === next;
}

class TypeWriter extends Component {
  constructor(props) {
    super(props);

    this.state = { visibleChars: 0 };

    this.setNextState = this.setNextState.bind(this);
  }

  componentDidMount() {
    this.start();
  }

  componentWillReceiveProps(nextProps) {
    const active = this.props.typing;
    const next = nextProps.typing;

    if (next === 0) {
      this.clearTimeout();
    } else if (!isEqual(active, next)) {
      this.setNextState(next);
    } else if (!isEqual(nextProps.children, this.props.children)) {
      this.setState({ visibleChars: 0 });
      this.start();
    }
  }

  shouldComponentUpdate(nextProps, nextState) {
    return (
      !isEqual(this.state.visibleChars, nextState.visibleChars) ||
      !isEqual(this.props.children, nextProps.children)
    );
  }

  componentDidUpdate(prevProps, prevState) {
    const {
      children,
      delayMap,
      onTyped,
      onTypingEnd
    } = this.props;
    const { visibleChars } = prevState;
    const currentToken = children[visibleChars];
    const nextToken = children[this.state.visibleChars];

    if (currentToken && onTyped) {
      onTyped(currentToken, visibleChars);
    }

    if (nextToken) {
      let timeout = this.getRandomTimeout();

      if (delayMap) {
        delayMap.forEach(({ at, delay }) => {
          if (isEqual(at, visibleChars) || currentToken.match(at)) {
            timeout += delay;
          }
        });
      }

      this.start(timeout);
    } else if (onTypingEnd) {
      onTypingEnd();
    }
  }

  componentWillUnmount() {
    this.clearTimeout();
  }

  setNextState(typing = this.props.typing) {
    this.setState({ visibleChars: this.state.visibleChars + typing });
  }

  getRandomTimeout() {
    const { maxDelay, minDelay } = this.props;

    return Math.round(Math.random() * (maxDelay - minDelay) + minDelay);
  }

  clearTimeout() {
    if (this.timeoutId) {
      clearTimeout(this.timeoutId);
    }
  }

  start(timeout = this.props.initialDelay) {
    this.clearTimeout();
    this.timeoutId = setTimeout(this.setNextState, timeout);
  }

  render() {
    const { children, ...props } = this.props;
    const { visibleChars } = this.state;
    const { fixed } = this.props;

    const visibleString = children.slice(0, visibleChars)

    let components = [(
      <Text
        { ...props }
        key="visible-string">
        {visibleString}
      </Text>
    )];
    if (fixed) {
      const invisibleString = children.slice(visibleChars)
      props.style = {
        ...props.style,
        opacity: 0,
      }
      components.push(
        <Text
          { ...props }
          key="invisible-string">
          {invisibleString}
        </Text>
      );
    }
    return (
      <Text>
        {components}
      </Text>
    );
  }
}

TypeWriter.propTypes = propTypes;
TypeWriter.defaultProps = defaultProps;

export default TypeWriter
<|endoftext|>


<commit_before>var hash = require('./murmerhash');
var Promise = null;
var isCordova = typeof cordova !== 'undefined';
var SERVER_DETECT = isCordova? '://':'filesystem:';

if(!isCordova) {
  window.ProgressEvent = function ProgressEvent(){}
}

/* Cordova File Cache x */
function FileCache(options){
  // cordova-promise-fs
  this._fs = options.fs;
  if(!this._fs) {
    throw new Error('Missing required option "fs". Add an instance of cordova-promise-fs.');
  }
  // Use Promises from fs.
  Promise = this._fs.Promise;

  // 'mirror' mirrors files structure from "serverRoot" to "localRoot"
  // 'hash' creates a 1-deep filestructure, where the filenames are hashed server urls (with extension)
  this._mirrorMode = options.mode !== 'hash';
  this._retry = options.retry || [500,1500,8000];
  this._cacheBuster = !!options.cacheBuster;

  // normalize path
  this._localRoot = options.localRoot || 'data';
  if(this._localRoot[this._localRoot.length -1] !== '/') this._localRoot += '/';
  if(this._localRoot[0] !== '/') this._localRoot = '/' + this._localRoot;

  this._serverRoot = options.serverRoot || '';
  if(!!this._serverRoot && this._serverRoot[this._serverRoot.length-1] !== '/') this._serverRoot += '/';
  if(this._serverRoot === './') this._serverRoot = '';

  // set internal variables
  this._downloading = [];    // download promises
  this._added = [];          // added files
  this._cached = {};         // cached files

  // list existing cache contents
  this.ready = this.list();
}

/**
 * Helper to cache all 'internalURL' and 'URL' for quick synchronous access
 * to the cached files.
 */
FileCache.prototype.list = function list(){
  var self = this;
  return new Promise(function(resolve,reject){
    self._fs.list(self._localRoot,'rfe').then(function(entries){
      self._cached = {};
      entries = entries.map(function(entry){
        self._cached[entry.fullPath] = {
          toInternalURL: isCordova? entry.toInternalURL(): entry.toURL(),
          toURL: entry.toURL(),
        };
        return entry.fullPath;
      });
      resolve(entries);
    },function(){
      resolve([]);
    });
  });
};

FileCache.prototype.add = function add(urls){
  if(typeof urls === 'string') urls = [urls];
  var self = this;
  urls.forEach(function(url){
    url = self.toServerURL(url);
    if(self._added.indexOf(url) === -1) {
      self._added.push(url);
    }
  });
  return self.isDirty();
};

FileCache.prototype.remove = function remove(urls,returnPromises){
  var promises = [];
  if(typeof urls === 'string') urls = [urls];
  var self = this;
  urls.forEach(function(url){
    var index = self._added.indexOf(self.toServerURL(url));
    if(index >= 0) self._added.splice(index,1);
    var path = self.toPath(url);
    promises.push(self._fs.remove(path));
    delete self._cached[path];
  });
  return returnPromises? Promise.all(promises): self.isDirty();
};

FileCache.prototype.getDownloadQueue = function(){
  var self = this;
  var queue = self._added.filter(function(url){
    return !self.isCached(url);
  });
  return queue;
};

FileCache.prototype.getAdded = function() {
  return this._added;
};

FileCache.prototype.isDirty = function isDirty(){
  return this.getDownloadQueue().length > 0;
};

FileCache.prototype.download = function download(onprogress){
  var fs = this._fs;
  var self = this;
  self.abort();

  return new Promise(function(resolve,reject){
    // make sure cache directory exists and that
    // we have retrieved the latest cache contents
    // to avoid downloading files we already have!
    fs.ensure(self._localRoot).then(function(){
      return self.list();
    }).then(function(){
      // no dowloads needed, resolve
      if(!self.isDirty()) {
        resolve(self);
        return;
      }

      // keep track of number of downloads!
      var queue = self.getDownloadQueue();
      var started = [];
      var index = self._downloading.length;
      var done = self._downloading.length;
      var total = self._downloading.length + queue.length;

      // download every file in the queue (which is the diff from _added with _cached)
      queue.forEach(function(url){
        var path = self.toPath(url);
        // augment progress event with index/total stats
        var onSingleDownloadProgress;
        if(typeof onprogress === 'function') {
          onSingleDownloadProgress = function(ev){
            ev.queueIndex = index;
            ev.queueSize = total;
            ev.url = url;
            ev.path = path;
            ev.percentage = index / total;
            if(ev.loaded > 0 && ev.total > 0 && index !== total){
               ev.percentage += (ev.loaded / ev.total) / total;
            }
            if(started.indexOf(url) < 0) {
              started.push(url);
              index++;
            }
            onprogress(ev);
          };
        }

        // callback
        var onDone = function(){
          done++;
          // when we're done
          if(done === total) {
            // reset downloads
            self._downloading = [];
            // check if we got everything
            self.list().then(function(){
              // final progress event!
              if(onSingleDownloadProgress) onSingleDownloadProgress(new ProgressEvent());
              // Yes, we're not dirty anymore!
              if(!self.isDirty()) {
                resolve(self);
              // Aye, some files got left behind!
              } else {
                reject(self.getDownloadQueue());
              }
            },reject);
          }
        };
        var downloadUrl = url;
        if(self._cacheBuster) downloadUrl += "?"+Date.now();
        var download = fs.download(url,path,{retry:self._retry},onSingleDownloadProgress);
        download.then(onDone,onDone);
        self._downloading.push(download);
      });
    },reject);
  });
};

FileCache.prototype.abort = function abort(){
  this._downloading.forEach(function(download){
    download.abort();
  });
  this._downloading = [];
};

FileCache.prototype.isCached = function isCached(url){
  url = this.toPath(url);
  return !!this._cached[url];
};

FileCache.prototype.clear = function clear(){
  this._cached = {};
  return this._fs.removeDir(this._localRoot);
};

/**
 * Helpers to output to various formats
 */
FileCache.prototype.toInternalURL = function toInternalURL(url){
  path = this.toPath(url);
  if(this._cached[path]) return this._cached[path].toInternalURL;
  return this._fs.toInternalURLSync(path);
};

FileCache.prototype.get = FileCache.prototype.toInternalURL;

FileCache.prototype.toDataURL = function toDataURL(url){
  return this._fs.toDataURL(this.toPath(url));
};

FileCache.prototype.toURL = function toInternalURL(url){
  path = this.toPath(url);
  return this._cached[path]? this._cached[path].toURL: url;
};

FileCache.prototype.toServerURL = function toServerURL(path){
  if(path[0] === '/') path = path.substr(1);
  return path.indexOf(SERVER_DETECT) < 0? this._serverRoot + path: path;
};

/**
 * Helper to transform remote URL to a local path (for cordova-promise-fs)
 */
FileCache.prototype.toPath = function toPath(url){
  if(this._mirrorMode) {
    url = url || '';
    len = this._serverRoot.length;
    if(url.substr(0,len) !== this._serverRoot) {
      if(url[0] === '/') url = url.substr(1);
      return this._localRoot + url;
    } else {
      return this._localRoot + url.substr(len);
    }
  } else {
    return this._localRoot + hash(url) + url.substr(url.lastIndexOf('.'));
  }
};

module.exports = FileCache;<commit_msg>fixed a minor bug in toServerURL<commit_after>var hash = require('./murmerhash');
var Promise = null;
var isCordova = typeof cordova !== 'undefined';

if(!isCordova) {
  window.ProgressEvent = function ProgressEvent(){}
}

/* Cordova File Cache x */
function FileCache(options){
  // cordova-promise-fs
  this._fs = options.fs;
  if(!this._fs) {
    throw new Error('Missing required option "fs". Add an instance of cordova-promise-fs.');
  }
  // Use Promises from fs.
  Promise = this._fs.Promise;

  // 'mirror' mirrors files structure from "serverRoot" to "localRoot"
  // 'hash' creates a 1-deep filestructure, where the filenames are hashed server urls (with extension)
  this._mirrorMode = options.mode !== 'hash';
  this._retry = options.retry || [500,1500,8000];
  this._cacheBuster = !!options.cacheBuster;

  // normalize path
  this._localRoot = options.localRoot || 'data';
  if(this._localRoot[this._localRoot.length -1] !== '/') this._localRoot += '/';
  if(this._localRoot[0] !== '/') this._localRoot = '/' + this._localRoot;

  this._serverRoot = options.serverRoot || '';
  if(!!this._serverRoot && this._serverRoot[this._serverRoot.length-1] !== '/') this._serverRoot += '/';
  if(this._serverRoot === './') this._serverRoot = '';

  // set internal variables
  this._downloading = [];    // download promises
  this._added = [];          // added files
  this._cached = {};         // cached files

  // list existing cache contents
  this.ready = this.list();
}

/**
 * Helper to cache all 'internalURL' and 'URL' for quick synchronous access
 * to the cached files.
 */
FileCache.prototype.list = function list(){
  var self = this;
  return new Promise(function(resolve,reject){
    self._fs.list(self._localRoot,'rfe').then(function(entries){
      self._cached = {};
      entries = entries.map(function(entry){
        self._cached[entry.fullPath] = {
          toInternalURL: isCordova? entry.toInternalURL(): entry.toURL(),
          toURL: entry.toURL(),
        };
        return entry.fullPath;
      });
      resolve(entries);
    },function(){
      resolve([]);
    });
  });
};

FileCache.prototype.add = function add(urls){
  if(typeof urls === 'string') urls = [urls];
  var self = this;
  urls.forEach(function(url){
    url = self.toServerURL(url);
    if(self._added.indexOf(url) === -1) {
      self._added.push(url);
    }
  });
  return self.isDirty();
};

FileCache.prototype.remove = function remove(urls,returnPromises){
  var promises = [];
  if(typeof urls === 'string') urls = [urls];
  var self = this;
  urls.forEach(function(url){
    var index = self._added.indexOf(self.toServerURL(url));
    if(index >= 0) self._added.splice(index,1);
    var path = self.toPath(url);
    promises.push(self._fs.remove(path));
    delete self._cached[path];
  });
  return returnPromises? Promise.all(promises): self.isDirty();
};

FileCache.prototype.getDownloadQueue = function(){
  var self = this;
  var queue = self._added.filter(function(url){
    return !self.isCached(url);
  });
  return queue;
};

FileCache.prototype.getAdded = function() {
  return this._added;
};

FileCache.prototype.isDirty = function isDirty(){
  return this.getDownloadQueue().length > 0;
};

FileCache.prototype.download = function download(onprogress){
  var fs = this._fs;
  var self = this;
  self.abort();

  return new Promise(function(resolve,reject){
    // make sure cache directory exists and that
    // we have retrieved the latest cache contents
    // to avoid downloading files we already have!
    fs.ensure(self._localRoot).then(function(){
      return self.list();
    }).then(function(){
      // no dowloads needed, resolve
      if(!self.isDirty()) {
        resolve(self);
        return;
      }

      // keep track of number of downloads!
      var queue = self.getDownloadQueue();
      var started = [];
      var index = self._downloading.length;
      var done = self._downloading.length;
      var total = self._downloading.length + queue.length;

      // download every file in the queue (which is the diff from _added with _cached)
      queue.forEach(function(url){
        var path = self.toPath(url);
        // augment progress event with index/total stats
        var onSingleDownloadProgress;
        if(typeof onprogress === 'function') {
          onSingleDownloadProgress = function(ev){
            ev.queueIndex = index;
            ev.queueSize = total;
            ev.url = url;
            ev.path = path;
            ev.percentage = index / total;
            if(ev.loaded > 0 && ev.total > 0 && index !== total){
               ev.percentage += (ev.loaded / ev.total) / total;
            }
            if(started.indexOf(url) < 0) {
              started.push(url);
              index++;
            }
            onprogress(ev);
          };
        }

        // callback
        var onDone = function(){
          done++;
          // when we're done
          if(done === total) {
            // reset downloads
            self._downloading = [];
            // check if we got everything
            self.list().then(function(){
              // final progress event!
              if(onSingleDownloadProgress) onSingleDownloadProgress(new ProgressEvent());
              // Yes, we're not dirty anymore!
              if(!self.isDirty()) {
                resolve(self);
              // Aye, some files got left behind!
              } else {
                reject(self.getDownloadQueue());
              }
            },reject);
          }
        };
        var downloadUrl = url;
        if(self._cacheBuster) downloadUrl += "?"+Date.now();
        var download = fs.download(url,path,{retry:self._retry},onSingleDownloadProgress);
        download.then(onDone,onDone);
        self._downloading.push(download);
      });
    },reject);
  });
};

FileCache.prototype.abort = function abort(){
  this._downloading.forEach(function(download){
    download.abort();
  });
  this._downloading = [];
};

FileCache.prototype.isCached = function isCached(url){
  url = this.toPath(url);
  return !!this._cached[url];
};

FileCache.prototype.clear = function clear(){
  this._cached = {};
  return this._fs.removeDir(this._localRoot);
};

/**
 * Helpers to output to various formats
 */
FileCache.prototype.toInternalURL = function toInternalURL(url){
  path = this.toPath(url);
  if(this._cached[path]) return this._cached[path].toInternalURL;
  return this._fs.toInternalURLSync(path);
};

FileCache.prototype.get = FileCache.prototype.toInternalURL;

FileCache.prototype.toDataURL = function toDataURL(url){
  return this._fs.toDataURL(this.toPath(url));
};

FileCache.prototype.toURL = function toInternalURL(url){
  path = this.toPath(url);
  return this._cached[path]? this._cached[path].toURL: url;
};

FileCache.prototype.toServerURL = function toServerURL(path){
  if(path[0] === '/') path = path.substr(1);
  return path.indexOf('://') < 0? this._serverRoot + path: path;
};

/**
 * Helper to transform remote URL to a local path (for cordova-promise-fs)
 */
FileCache.prototype.toPath = function toPath(url){
  if(this._mirrorMode) {
    url = url || '';
    len = this._serverRoot.length;
    if(url.substr(0,len) !== this._serverRoot) {
      if(url[0] === '/') url = url.substr(1);
      return this._localRoot + url;
    } else {
      return this._localRoot + url.substr(len);
    }
  } else {
    return this._localRoot + hash(url) + url.substr(url.lastIndexOf('.'));
  }
};

module.exports = FileCache;<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict'

const fs = require('fs')
const getRepo = require('get-pkg-repo')
const assert = require('assert')
const Travis = require('travis-ci')
const exec = require('child_process').execSync
const ansi = require('ansi-escapes')
const ora = require('ora')
const chalk = require('chalk')
const resolve = require('path').resolve

const dir = resolve(process.argv[2] || '.')

const repo = getRepo(require(`${dir}/package.json`))
assert(repo.user)
assert(repo.project)

const sha = exec('git log --format="%H" -n1', {
  cwd: dir
}).toString().trim()

const travis = new Travis({ version: '2.0.0' })

const getBuilds = cb => {
  travis
  .repos(repo.user, repo.project)
  .builds
  .get(cb)
}

const findCommit = commits => commits.find(c => c.sha === sha)
const findBuild = (builds, commitId) => builds.find(b => b.commit_id === commitId)

const getBuild = cb => {
  getBuilds((err, res) => {
    if (err) return cb(err)
    const commit = findCommit(res.commits)
    if (!commit) return getBuild(cb)
    const build = findBuild(res.builds, commit.id)
    if (build) cb(null, build)
    else getBuild(cb)
  })
}

const getJob = (id, cb) => {
  travis
  .jobs(id)
  .get((err, res) => {
    if (err) return cb(err)
    cb(null, res.job)
  })
}

let lastLines = 0
const render = results => {
  let first = true

  Object.keys(results).forEach(os => {
    const versions = Object.keys(results[os])
    if (!versions.length) return

    if (first) {
      spinner.stop()
      process.stdout.write(ansi.eraseLines(lastLines))
      if (lastLines) {
        process.stdout.write(ansi.cursorPrevLine)
        process.stdout.write(ansi.eraseLine)
      }
      lastLines = 0
      first = false
    }

    console.log()
    console.log(chalk.gray(os))
    console.log()

    versions.forEach(version => {
      console.log(`  ${check(results[os][version])} node ${version}`)
    })

    console.log()

    lastLines += 4 + versions.length
  })
}

const check = state =>
  state === 'failed' ? chalk.red('×')
  : state === 'passed' ? chalk.green('✓')
  : chalk.yellow('.')

const spinner = ora('Loading build').start()

getBuild((err, build) => {
  if (err) throw err

  const results = {
    osx: {},
    linux: {}
  }

  spinner.text = 'Loading jobs'

  build.job_ids.forEach(jobId => {
    const check = (err, job) => {
      if (err) throw err
      results[job.config.os][job.config.node_js] = job.state
      render(results)
      if (job.state === 'created') getJob(jobId, check)
    }
    getJob(jobId, check)
  })
})
<commit_msg>fix wrong state name<commit_after>#!/usr/bin/env node
'use strict'

const fs = require('fs')
const getRepo = require('get-pkg-repo')
const assert = require('assert')
const Travis = require('travis-ci')
const exec = require('child_process').execSync
const ansi = require('ansi-escapes')
const ora = require('ora')
const chalk = require('chalk')
const resolve = require('path').resolve

const dir = resolve(process.argv[2] || '.')

const repo = getRepo(require(`${dir}/package.json`))
assert(repo.user)
assert(repo.project)

const sha = exec('git log --format="%H" -n1', {
  cwd: dir
}).toString().trim()

const travis = new Travis({ version: '2.0.0' })

const getBuilds = cb => {
  travis
  .repos(repo.user, repo.project)
  .builds
  .get(cb)
}

const findCommit = commits => commits.find(c => c.sha === sha)
const findBuild = (builds, commitId) => builds.find(b => b.commit_id === commitId)

const getBuild = cb => {
  getBuilds((err, res) => {
    if (err) return cb(err)
    const commit = findCommit(res.commits)
    if (!commit) return getBuild(cb)
    const build = findBuild(res.builds, commit.id)
    if (build) cb(null, build)
    else getBuild(cb)
  })
}

const getJob = (id, cb) => {
  travis
  .jobs(id)
  .get((err, res) => {
    if (err) return cb(err)
    cb(null, res.job)
  })
}

let lastLines = 0
const render = results => {
  let first = true

  Object.keys(results).forEach(os => {
    const versions = Object.keys(results[os])
    if (!versions.length) return

    if (first) {
      spinner.stop()
      process.stdout.write(ansi.eraseLines(lastLines))
      if (lastLines) {
        process.stdout.write(ansi.cursorPrevLine)
        process.stdout.write(ansi.eraseLine)
      }
      lastLines = 0
      first = false
    }

    console.log()
    console.log(chalk.gray(os))
    console.log()

    versions.forEach(version => {
      console.log(`  ${check(results[os][version])} node ${version}`)
    })

    console.log()

    lastLines += 4 + versions.length
  })
}

const check = state =>
  state === 'failed' ? chalk.red('×')
  : state === 'passed' ? chalk.green('✓')
  : chalk.yellow('.')

const spinner = ora('Loading build').start()

getBuild((err, build) => {
  if (err) throw err

  const results = {
    osx: {},
    linux: {}
  }

  spinner.text = 'Loading jobs'

  build.job_ids.forEach(jobId => {
    const check = (err, job) => {
      if (err) throw err
      results[job.config.os][job.config.node_js] = job.state
      render(results)
      if (job.state === 'started') getJob(jobId, check)
    }
    getJob(jobId, check)
  })
})
<|endoftext|>


<commit_before>var app = require('express')();
var http = require('http').Server(app);

app.get('/', function(req, res){
  res.send('
Hello world
');
});

var port = process.env.PORT || 3000;
http.listen(port function(){
  console.log('listening on *:' + port);
});
<commit_msg>comma<commit_after>var app = require('express')();
var http = require('http').Server(app);

app.get('/', function(req, res){
  res.send('
Hello world
');
});

var port = process.env.PORT || 3000;
http.listen(port, function(){
  console.log('listening on *:' + port);
});
<|endoftext|>


<commit_before>var React = require('react');
var ReactDom = require('react-dom');
var f1DOM = require('f1-dom');
var merge = require('deep-extend');

class ReactF1 extends React.Component {

  constructor(props) {
    super(props)

    this.state = {
      f1: null,
      f1State: null
    };
  }

  setupListenersFromProps(props) {
    this.setState({
      onUpdate: props.onUpdate,
      onState: props.onState
    });
  }

  handleUpdate() {
    if(this.state.onUpdate) {
      this.state.onUpdate.apply(undefined, arguments);
    }
  }

  handleState() {
    if(this.state.onState) {
      this.state.onState.apply(undefined, arguments);
    }
  }

  componentWillReceiveProps(nextProps) {
    var states;

    if(nextProps.states) {

      merge(
        this.state.states,
        nextProps.states
      );

      this.setState({
        states: this.state.states
      });

      // force an update to f1 since we received new props
      this.state.f1.update();
    }

    if(nextProps.state !== this.state.f1State) {
      if(this.state.f1) {
        this.state.f1.go(nextProps.state, nextProps.onComplete);

        this.setState({
          f1State: nextProps.state
        });
      }
    }

    this.setupListenersFromProps(nextProps);
  }

  componentDidMount() {
    var el = ReactDom.findDOMNode(this);
    var f1 = f1DOM({
      el: el,
      states: this.props.states,
      transitions: this.props.transitions
    });

    f1.on('state', this.handleState.bind(this));
    f1.on('update', this.handleUpdate.bind(this));
    this.setupListenersFromProps(this.props);

    this.setState({
      f1: f1,
      f1State: this.props.state,
      states: this.props.states
    });

    f1.init(this.props.state);
  }

  componentWillUnmount() {
    if(this.state.f1) {
      this.state.f1.destroy();
    }
  }

  render() {
    var style = this.props.style;

    if(!this.state.f1) {
      style = merge(
        {},
        this.props.style,
        {
          display: 'none'
        }
      );
    }

    return <div
      {...this.props}
      style={style}
    >
      { this.props.children }
    </div>;
  }
}

function findTargets(children, targets) {
  targets = targets || {};

  React.Children.forEach(children, function(child) {
    if(child.props) {
      var targetName = child.props['f1-target'];

      if(targetName) {
        targets[ targetName ] = child;
      }

      if(child.props.children) {
        findTargets(child.props.children, targets);
      }
    }
  });

  return targets;
}

module.exports = ReactF1;<commit_msg>Added a check to see if state.f1 exists before update<commit_after>var React = require('react');
var ReactDom = require('react-dom');
var f1DOM = require('f1-dom');
var merge = require('deep-extend');

class ReactF1 extends React.Component {

  constructor(props) {
    super(props)

    this.state = {
      f1: null,
      f1State: null
    };
  }

  setupListenersFromProps(props) {
    this.setState({
      onUpdate: props.onUpdate,
      onState: props.onState
    });
  }

  handleUpdate() {
    if(this.state.onUpdate) {
      this.state.onUpdate.apply(undefined, arguments);
    }
  }

  handleState() {
    if(this.state.onState) {
      this.state.onState.apply(undefined, arguments);
    }
  }

  componentWillReceiveProps(nextProps) {
    var states;

    if(nextProps.states) {

      merge(
        this.state.states,
        nextProps.states
      );

      this.setState({
        states: this.state.states
      });

      // force an update to f1 since we received new props
      if(this.state.f1) {
        this.state.f1.update();
      }
    }

    if(nextProps.state !== this.state.f1State) {
      if(this.state.f1) {
        this.state.f1.go(nextProps.state, nextProps.onComplete);

        this.setState({
          f1State: nextProps.state
        });
      }
    }

    this.setupListenersFromProps(nextProps);
  }

  componentDidMount() {
    var el = ReactDom.findDOMNode(this);
    var f1 = f1DOM({
      el: el,
      states: this.props.states,
      transitions: this.props.transitions
    });

    f1.on('state', this.handleState.bind(this));
    f1.on('update', this.handleUpdate.bind(this));
    this.setupListenersFromProps(this.props);

    this.setState({
      f1: f1,
      f1State: this.props.state,
      states: this.props.states
    });

    f1.init(this.props.state);
  }

  componentWillUnmount() {
    if(this.state.f1) {
      this.state.f1.destroy();
    }
  }

  render() {
    var style = this.props.style;

    if(!this.state.f1) {
      style = merge(
        {},
        this.props.style,
        {
          display: 'none'
        }
      );
    }

    return <div
      {...this.props}
      style={style}
    >
      { this.props.children }
    </div>;
  }
}

function findTargets(children, targets) {
  targets = targets || {};

  React.Children.forEach(children, function(child) {
    if(child.props) {
      var targetName = child.props['f1-target'];

      if(targetName) {
        targets[ targetName ] = child;
      }

      if(child.props.children) {
        findTargets(child.props.children, targets);
      }
    }
  });

  return targets;
}

module.exports = ReactF1;<|endoftext|>


<commit_before>'use strict';
var Promise = require('bluebird');
var _ = require('lodash');
var fs = require('fs');
var events = require('events');

var readdir = Promise.promisify(fs.readdir) ;

module.exports = Tendril;

function Tendril() {

  // function constructors
  var constructors = {};

  // loaded services
  var services = { tendril: Promise.resolve(tendril) };

  // services which are not lazily loaded are loaded at the first function
  var requested = [];

  // Chain is inner promise loop, used to sequence user function calls
  var chain = Promise.resolve(null);

  // used to emit the `serviceLoad` event
  var eventEmitter = new events.EventEmitter();

  /*
   * @param {Function|Array<paramNames..,fn>} - param names are service names
   */
  function tendril(fn, error) {

    // default values
    fn = fn || _.noop;
    error = error || function (err) {
      setImmediate(function () {
        throw err;
      });
    };

    var constructor = getConstructor(fn);

    // user functions must  complete in order, regardless of dependencies
    chain = chain.then(function () {

      // resolve non-lazy services
      return Promise.map(requested, getService);
    }).then(function () {

      // resolve requested services, and pass them into the function
      return Promise.map(constructor.params, getService).spread(constructor.fn);
    }).then(null, error);

    return tendril;
  }

  /*
   * @param name - event name (e.g. serviceLoad)
   * @param fn - callback fn -> { name: 'serviceName', instance: {Service} }
   */
  tendril.on = function (name, fn) {
    eventEmitter.on(name, fn);
    return tendril;
  };

  /*
   * @typedef {Object} Crawl
   *
   * @param {String} path - absolute path of directory to crawl
   * @param {String} [postfix=''] - String to append to filenames as services
   * @param {Boolean} [lazy=true] - only load if required by another service
   */

  /*
   * crawl a directory
   *
   * @param {Crawl|Array<Crawl>} crawl
   */
  tendril.crawl = function (crawl) {

    if (Array.isArray(crawl)) {
      _.each(crawl, tendril.crawl);
      return tendril;
    }

    // crawling a directory blocks the resolution chain
    chain = readdir(crawl.path).map(function (file) {
      var isDir = /^([^.]|\.\.)+$/.test(file);
      var isJsFile = /\.js$/.test(file);

      var serviceName = file.replace(/\.js$/, '') + (crawl.postfix || '');
      var requirePath = crawl.path + '/' + file;

      // verify index.js exists
      if (isDir) {
        return readdir(requirePath).then(function (files) {
          if (_.contains(files, 'index.js')) {
            var service = require(requirePath);
            return tendril.include(serviceName, service, true, crawl.lazy);
          }
        });
      } else if (isJsFile) {
        var service = require(requirePath);
        return tendril.include(serviceName, service, true, crawl.lazy);
      }
    }).then(chain);

    return tendril;
  };

  /*
   * @param {String|Object} name - if object, keys are names and values services
   * @param {Anything|Function} constructor - the service, or resolved
   * @param {Boolean} [shouldInject=true] - should attempt to inject function
   * @param {Boolean} [isLazy=true] - only load if required by a sub-service
   */
  tendril.include = function include(name, constructor, inject, lazy) {
    inject = inject == null ? true : inject;
    lazy = lazy == null ? true : lazy;

    // already initialized service
    if (!inject) {
      services[name] = Promise.resolve(constructor);
    }

    if (!lazy) {
      requested.push(name);
    }

    // Including an object, where values are services and keys are names
    if (typeof name === 'object') {
      _.forEach(name, function (constructor, serviceName) {
        tendril.include(serviceName, constructor, inject);
      });

      // constructor is a function or has a setup function on it
    } else if (inject && (typeof constructor === 'function' ||
        typeof constructor === 'object' &&
        typeof constructor.setup === 'function')) {

      if (typeof constructor === 'object') {
        constructor = constructor.setup;
      }

      constructors[name] = getConstructor(constructor);
    } else if (inject && Array.isArray(constructor)) {
      constructors[name] = getConstructor(constructor);
    } else {
      services[name] = Promise.resolve(constructor);
    }

    return tendril;
  };

  /*
   * returns a service
   *
   * @param {String} name
   */
  function getService(name) {
    if (_.isArray(name)) {
      return Promise.all(_.map(name, getService));
    }

    if (services[name]) {
      return services[name];
    }

    if (!constructors[name]) {
      return Promise.reject(missingDependencyError(name, constructors));
    }

    var circle = circularDependencies(name, name, constructors);
    if (circle) {
      return Promise.reject(new Error('Circular Dependency: ' +
                                       [name].concat(circle).join(' --> ')));
    }

    var constructor = constructors[name];

    services[name] = Promise.map(constructor.params, getService)
    .spread(constructor.fn)
    .tap(function () {
      eventEmitter.emit('serviceLoad', {
        name: name,
        instance: services[name]
      });
    });

    return services[name];
  }

  return tendril;
}

function missingDependencyError(name, constructors) {
  var message = 'Missing Dependency: ' + name;
  var dependencies = _.mapValues(constructors, function (constructor) {
    return constructor.params;
  });
  var missing = _.reduce(dependencies, function (missing, dep, service) {
    if (_.contains(dep, name)) {
      return missing.concat(service);
    }
    return missing;
  }, []);
  if (missing.length) {
    message += '\nDepended on by: ' + missing.join(', ');
  }

  return new Error(message);
}

/*
 * typedef {Object} Constructor
 *
 * @param {Function} fn
 * @param {Array<String>} params
 */

/*
 * @param {String} rootName
 * @param {String} childName
 * @param {Constructor} constructor
 *
 * @returns {Array<String>|null} - Service names, null if no circular deps
 */
function circularDependencies(rootName, childName, constructors) {
  var constructor = constructors[childName];
  if (!rootName || !constructor) {
    return null;
  }

  var containsSelf = _.contains(constructor.params, rootName);

  if (containsSelf) {
    return [rootName];
  }

  var innerCircularDependencies = _.reduce(constructor.params,
    function (circle, serviceName) {
    var deeper = circularDependencies(rootName, serviceName, constructors);

    if (deeper) {
      return circle.concat([serviceName]).concat(deeper);
    }

    return circle;

  }, []);

  if (innerCircularDependencies.length) {
    return innerCircularDependencies;
  }

  return null;
}

/*
 * @param {Function|Array<...Function>} fn
 *
 * @returns {Constructor}
 */
function getConstructor(fn) {
  if (Array.isArray(fn)) {
    var func = fn.pop();
    var params = fn;
    return {
      fn: func,
      params: params
    };
  } else {
    return {
      fn: fn,
      params: getParams(fn)
    };
  }
}

/*
 * @param {Function|Array<Function>} fn
 *
 * @returns {Array<String>} - parameter names
 */
function getParams(fn) {
  if (!fn) return [];

  var functionExp = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
  var commentsExp = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
  var argExp = /^\s*(\S+?)\s*$/;

  var fnString = fn.toString().replace(commentsExp, '');
  var match = fnString.match(functionExp);
  var params = match && match[1];

  if (!match || !params) return [];

  return _.map(params.split(','), function (param) {
    return param.match(argExp)[1];
  });
}
<commit_msg>updated comments<commit_after>'use strict';
var Promise = require('bluebird');
var _ = require('lodash');
var fs = require('fs');
var events = require('events');

var readdir = Promise.promisify(fs.readdir) ;

module.exports = Tendril;

function Tendril() {

  // function constructors
  var constructors = {};

  // loaded services
  var services = { tendril: Promise.resolve(tendril) };

  // services which are not lazily loaded are loaded at the first function
  var requested = [];

  // Chain is inner promise loop, used to sequence user function calls
  var chain = Promise.resolve(null);

  // used to emit the `serviceLoad` event
  var eventEmitter = new events.EventEmitter();

  /*
   * @param {Function|Array<paramNames..,fn>} - param names are service names
   */
  function tendril(fn, error) {

    // default values
    fn = fn || _.noop;
    error = error || function (err) {
      setImmediate(function () {
        throw err;
      });
    };

    var constructor = getConstructor(fn);

    // user functions must  complete in order, regardless of dependencies
    chain = chain.then(function () {

      // resolve non-lazy services
      return Promise.map(requested, getService);
    }).then(function () {

      // resolve requested services, and pass them into the function
      return Promise.map(constructor.params, getService).spread(constructor.fn);
    }).then(null, error);

    return tendril;
  }

  /*
   * @param name - event name (e.g. serviceLoad)
   * @param fn - callback fn -> { name: 'serviceName', instance: {Service} }
   */
  tendril.on = function (name, fn) {
    eventEmitter.on(name, fn);
    return tendril;
  };

  /*
   * @typedef {Object} Crawl
   *
   * @param {String} path - absolute path of directory to crawl
   * @param {String} [postfix=''] - String to append to filenames as services
   * @param {Boolean} [lazy=true] - only load if required by another service
   */

  /*
   * crawl a directory
   *
   * @param {Crawl|Array<Crawl>} crawl
   */
  tendril.crawl = function (crawl) {

    if (Array.isArray(crawl)) {
      _.each(crawl, tendril.crawl);
      return tendril;
    }

    // crawling a directory blocks the resolution chain
    chain = readdir(crawl.path).map(function (file) {
      var isDir = /^([^.]|\.\.)+$/.test(file);
      var isJsFile = /\.js$/.test(file);

      var serviceName = file.replace(/\.js$/, '') + (crawl.postfix || '');
      var requirePath = crawl.path + '/' + file;

      // verify index.js exists
      if (isDir) {
        return readdir(requirePath).then(function (files) {
          if (_.contains(files, 'index.js')) {
            var service = require(requirePath);
            return tendril.include(serviceName, service, true, crawl.lazy);
          }
        });
      } else if (isJsFile) {
        var service = require(requirePath);
        return tendril.include(serviceName, service, true, crawl.lazy);
      }
    }).then(chain);

    return tendril;
  };

  /*
   * @param {String|Object} name - if object, keys are names and values services
   * @param {Anything|Function} constructor - the service, or resolved
   * @param {Boolean} [shouldInject=true] - should attempt to inject function
   * @param {Boolean} [isLazy=true] - only load if required by a sub-service
   */
  tendril.include = function include(name, constructor, inject, lazy) {
    inject = inject == null ? true : inject;
    lazy = lazy == null ? true : lazy;

    // already initialized service
    if (!inject) {
      services[name] = Promise.resolve(constructor);
    }

    if (!lazy) {
      requested.push(name);
    }

    // Including an object, where values are services and keys are names
    if (typeof name === 'object') {
      _.forEach(name, function (constructor, serviceName) {
        tendril.include(serviceName, constructor, inject);
      });

      // constructor is a function or has a setup function on it
    } else if (inject && (typeof constructor === 'function' ||
        typeof constructor === 'object' &&
        typeof constructor.setup === 'function')) {

      if (typeof constructor === 'object') {
        constructor = constructor.setup;
      }

      constructors[name] = getConstructor(constructor);
    } else if (inject && Array.isArray(constructor)) {
      constructors[name] = getConstructor(constructor);
    } else {
      services[name] = Promise.resolve(constructor);
    }

    return tendril;
  };

  /*
   * returns a service
   *
   * @param {String} name
   */
  function getService(name) {
    if (_.isArray(name)) {
      return Promise.all(_.map(name, getService));
    }

    if (services[name]) {
      return services[name];
    }

    if (!constructors[name]) {
      return Promise.reject(missingDependencyError(name, constructors));
    }

    var circle = circularDependencies(name, name, constructors);
    if (circle) {
      return Promise.reject(new Error('Circular Dependency: ' +
                                       [name].concat(circle).join(' --> ')));
    }

    var constructor = constructors[name];

    services[name] = Promise.map(constructor.params, getService)
    .spread(constructor.fn)
    .tap(function () {
      eventEmitter.emit('serviceLoad', {
        name: name,
        instance: services[name]
      });
    });

    return services[name];
  }

  return tendril;
}

/*
 * @param {String} name
 * @param {Object<String, Constructor>} constructors
 *
 * @returns {Error}
 */
function missingDependencyError(name, constructors) {
  var message = 'Missing Dependency: ' + name;
  var dependencies = _.mapValues(constructors, function (constructor) {
    return constructor.params;
  });
  var missing = _.reduce(dependencies, function (missing, dep, service) {
    if (_.contains(dep, name)) {
      return missing.concat(service);
    }
    return missing;
  }, []);
  if (missing.length) {
    message += '\nDepended on by: ' + missing.join(', ');
  }

  return new Error(message);
}

/*
 * typedef {Object} Constructor
 *
 * @param {Function} fn
 * @param {Array<String>} params
 */

/*
 * @param {String} rootName
 * @param {String} childName
 * @param {Object<String, Constructor>} constructors
 *
 * @returns {Array<String>|null} - Service names, null if no circular deps
 */
function circularDependencies(rootName, childName, constructors) {
  var constructor = constructors[childName];
  if (!rootName || !constructor) {
    return null;
  }

  var containsSelf = _.contains(constructor.params, rootName);

  if (containsSelf) {
    return [rootName];
  }

  var innerCircularDependencies = _.reduce(constructor.params,
    function (circle, serviceName) {
    var deeper = circularDependencies(rootName, serviceName, constructors);

    if (deeper) {
      return circle.concat([serviceName]).concat(deeper);
    }

    return circle;

  }, []);

  if (innerCircularDependencies.length) {
    return innerCircularDependencies;
  }

  return null;
}

/*
 * @param {Function|Array<...Function>} fn
 *
 * @returns {Constructor}
 */
function getConstructor(fn) {
  if (Array.isArray(fn)) {
    var func = fn.pop();
    var params = fn;
    return {
      fn: func,
      params: params
    };
  } else {
    return {
      fn: fn,
      params: getParams(fn)
    };
  }
}

/*
 * @param {Function|Array<Function>} fn
 *
 * @returns {Array<String>} - parameter names
 */
function getParams(fn) {
  if (!fn) return [];

  var functionExp = /^function\s*[^\(]*\(\s*([^\)]*)\)/m;
  var commentsExp = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
  var argExp = /^\s*(\S+?)\s*$/;

  var fnString = fn.toString().replace(commentsExp, '');
  var match = fnString.match(functionExp);
  var params = match && match[1];

  if (!match || !params) return [];

  return _.map(params.split(','), function (param) {
    return param.match(argExp)[1];
  });
}
<|endoftext|>


<commit_before>/**
 * Build and run BDD flows with before/after hooks, describe, it
 *
 * Licensed under MIT.
 * Copyright (c) 2013 David Smith <https://github.com/codeactual/>
 */

/*jshint node:true*/
'use strict';

module.exports = {
  Bddflow: Bddflow,
  create: create,
  require: require // Allow tests to use component-land require.
};

var Batch = require('batch');
var bind = require('bind');
var clone = require('clone');
var configurable = require('configurable.js');
var extend = require('extend');

// Match properties that should not be 'inherited' by it(), hooks, or all.
var defOmitContextRegex = {
  all: [/^__|^(it|describe|before|beforeEach|after|afterEach|settings|set|get)$/],
  it: [],
  hook: []
};

function create() { return new Bddflow(); }

/**
 * Flow configuration and execution.
 */
function Bddflow() {
  this.settings = {
    done: noOp, // Batch#end callback that fires after flow completes.

    // Propagate to each new Describe instance:
    itWrap: null,
    omitContextRegex: clone(defOmitContextRegex),
    path: [], // Names of ancestor describe levels to the currently executing it().
    grep: /.?/, // Filters it() execution by "current path + it() name".
    grepv: null // Omits it() execution by "current path + it() name".
  };
  this.rootDescribes = [];
  this.batch = new Batch();
  this.seedProps = {}; // Will me merged into initial hook/describe/it context.
  this.running = false;
}
Bddflow.sharedConfigKeys = ['itWrap', 'omitContextRegex', 'path', 'grep', 'grepv'];

configurable(Bddflow.prototype);

/**
 * Add a property to the initial hook/describe/it shared context.
 *
 * @param {string} key
 * @param {mixed} val
 * @return {object} this
 */
Bddflow.prototype.addContextProp = function(key, val) {
  this.seedProps[key] = val;
  return this;
};

/**
 * Add a top-level describe().
 *
 * @param {string} name
 * @param {function} cb
 */
Bddflow.prototype.addRootDescribe = function(name, cb) {
  var self = this;
  var desc = new Describe(name);

  var bddFlowConfig = {}; // Propagate selected settings.
  Bddflow.sharedConfigKeys.forEach(function(key) {
    bddFlowConfig[key] = self.get(key);
  });
  desc.set('bddFlowConfig', bddFlowConfig);

  desc.describe(name, cb);
  this.rootDescribes.push(desc);
  return this;
};

/**
 * Prevent a type of flow function from 'inheriting' specific context properties
 * from enclosing/subsequently-executed flow functions.
 *
 * @param {string} 'it', 'hook'
 * @param {object} RegExp instance.
 * @return {object} this
 */
Bddflow.prototype.hideContextProp = function(type, regex) {
  this.get('omitContextRegex')[type].push(regex);
  return this;
};

/**
 * Check if run() has been called.
 *
 * @return {boolean}
 */
Bddflow.prototype.isRunning = function() {
  return this.running;
};

/**
 * Run collected describe() layers.
 */
Bddflow.prototype.run = function() {
  var self = this;

  this.running = true;

  var batch = new Batch();
  batch.concurrency = 1;
  this.rootDescribes.forEach(function(desc) {
    batch.push(function(taskDone) {
      extend(desc, self.seedProps);
      runSteps(desc.__steps, taskDone);
    });
  });
  batch.end(this.get('done'));
};

/**
 * Filter 'this' into an object with properties that can be 'inherited'
 * between hooks/describe/it.
 *
 * Static used in other classes via call(). Exposed for test access.
 *
 * @param {string} type 'describe', 'it', 'hook'
 * @return {object}
 */
Bddflow.getInheritableContext = function(type) {
  var self = this;
  var omitContextRegex = this.get('bddFlowConfig').omitContextRegex;
  var regex = omitContextRegex.all.concat(type ? omitContextRegex[type] : []);

  return Object.keys(this).reduce(function(memo, key) {
    var omit = false;
    regex.forEach(function(re) {
      omit = omit || re.test(key);
    });
    if (omit) {
      return memo;
    }
    memo[key] = self[key];
    return memo;
  }, {});
};

/**
 * Augment 'this' with a new non-enumerable/configrable property intended
 * for internal-use only. Help avoid conflicts with properties 'inherited'
 * via getInheritableContext.
 *
 * Static used in other classes via call(). Exposed for test access.
 *
 * @param {string} key
 * @param {mixed} value
 */
Bddflow.addInternalProp = function(key, value) {
  Object.defineProperty(
    this, '__' + key,
    {value: value, enumerable: false, configurable: false, writable: true}
  );
};

/**
 * Callback context for before(), beforeEach(), etc.
 *
 * @param {string} name Of enclosing describe().
 */
function HookContext(name) {
  Bddflow.addInternalProp.call(this, 'name', name);
}
configurable(HookContext.prototype);
HookContext.prototype.getInheritableContext = Bddflow.getInheritableContext;

// Auto-terminating callback for use with Batch#push.
Bddflow.defaultHookImpl = function(done) { done(); };

/**
 * Container for a before(), beforeEach(), etc. method set.
 */
function HookSet() {
  this.before = Bddflow.defaultHookImpl;
  this.beforeEach = Bddflow.defaultHookImpl;
  this.after = Bddflow.defaultHookImpl;
  this.afterEach = Bddflow.defaultHookImpl;
}

/**
 * @param {string} name Subject expectation.
 * @param {string} name Test subject.
 */
function ItCallback(name, cb) {
  Bddflow.addInternalProp.call(this, 'name', name);
  this.cb = cb;
}

/**
 * A describe()'s properties, internal hooks, and nested steps (describe/it).
 *
 * @param {string} name Subject expected to exhibit some behavior.
 */
function Describe(name) {
  Bddflow.addInternalProp.call(this, 'name', name);
  Bddflow.addInternalProp.call(this, 'steps', []);
  Bddflow.addInternalProp.call(this, 'hooks', new HookSet());
  this.settings = {
    bddFlowConfig: {}
  };
}
configurable(Describe.prototype);
Describe.prototype.getInheritableContext = Bddflow.getInheritableContext;

/**
 * Add an it() step.
 *
 * @param {string} name
 * @param {function} cb Batch#push compat.
 */
Describe.prototype.it = function(name, cb) {
  this.__steps.push(new ItCallback(name, cb));
};

/**
 * Add a describe() step.
 *
 * @param {string} name
 * @param {function} cb Batch#push compat.
 */
Describe.prototype.describe = function(name, cb) {
  var self = this;
  var step = function(done) {
    var desc = new Describe(name); // Collect nested steps.
    var bddFlowConfig = clone(self.get('bddFlowConfig'));
    bddFlowConfig.path.push(name);
    desc.set('bddFlowConfig', bddFlowConfig);
    extend(desc, self.getInheritableContext());
    cb.call(desc);

    var hc = new HookContext(name);
    hc.set('bddFlowConfig', self.get('bddFlowConfig'));

    var batch = new Batch();

    batch.push(function(done) {
      extend(hc, desc.getInheritableContext('hook'));
      function asyncCb() {
        extend(desc, hc.getInheritableContext('hook'));
        done();
      }
      var hook = desc.__hooks.before;
      if (hook.length) { // Custom before() expects callback arg.
        desc.__hooks.before.call(hc, asyncCb);
      } else {
        desc.__hooks.before.call(hc);
        asyncCb();
      }
    });

    batch.push(function(done) { // Wrap hooks around each internal describe()/it()
      desc.__steps = desc.__steps.map(function(step) {
        if (step instanceof DescribeCallback) {
          extend(desc, hc.getInheritableContext());
          return new DescribeCallback(step.__name, bind(desc, step.cb));
        }

        var itPath = bddFlowConfig.path.concat(step.__name);
        if (bddFlowConfig.grepv) {
          if (bddFlowConfig.grepv.test(itPath.join(' '))) {
            return new ItCallback(step.__name, batchNoOp);
          }
        } else if (bddFlowConfig.grep) {
          if (!bddFlowConfig.grep.test(itPath.join(' '))) {
            return new ItCallback(step.__name, batchNoOp);
          }
        }

        return new DescribeCallback(step.__name, function(done) { // instanceof ItCallback
          var batch = new Batch();
          batch.push(function(done) {
            extend(hc, desc.getInheritableContext('hook'));
            function asyncCb() {
              extend(desc, hc.getInheritableContext('hook'));
              done();
            }
            var hook = desc.__hooks.beforeEach;
            if (hook.length) { // Custom beforeEach() expects callback arg.
              desc.__hooks.beforeEach.call(hc, asyncCb);
            } else {
              desc.__hooks.beforeEach.call(hc);
              asyncCb();
            }
          });
          batch.push(function(done) {
            var itContext = {};
            extend(itContext, desc.getInheritableContext('it'));
            itContext.__name = step.__name;
            itContext.__path = itPath;

            var itWrap = self.get('bddFlowConfig').itWrap || defItWrap;
            itWrap(step.__name, function() {
              var wrapContext = this;
              var mergedContext = extend(itContext, wrapContext);
              if (step.cb.length) { // Custom afterEach() expects callback arg.
                step.cb.call(mergedContext, done);
              } else {
                step.cb.call(mergedContext);
                done();
              }
            });
          });
          batch.push(function(done) {
            function asyncCb() {
              extend(desc, hc.getInheritableContext('hook'));
              done();
            }
            var hook = desc.__hooks.afterEach;
            if (hook.length) { // Custom afterEach() expects callback arg.
              desc.__hooks.afterEach.call(hc, asyncCb);
            } else {
              desc.__hooks.afterEach.call(hc);
              asyncCb();
            }
          });
          batch.concurrency = 1;
          batch.end(done);
        });
      });

      runSteps(desc.__steps, done);
    });

    batch.push(function(done) {
      extend(hc, desc.getInheritableContext('hook'));
      function asyncCb() {
        extend(desc, hc.getInheritableContext('hook'));
        done();
      }
      var hook = desc.__hooks.after;
      if (hook.length) { // Custom after() expects callback arg.
        desc.__hooks.after.call(hc, asyncCb);
      } else {
        desc.__hooks.after.call(hc);
        asyncCb();
      }
    });

    batch.concurrency = 1;
    batch.end(done);
  };
  this.__steps.push(new DescribeCallback(name, step));
};

/**
 * Override the default no-op before() hook.
 *
 * @param {function} cb
 */
Describe.prototype.before = function(cb) { this.__hooks.before = cb; };

/**
 * Override the default no-op beforeEach() hook.
 *
 * @param {function} cb
 */
Describe.prototype.beforeEach = function(cb) { this.__hooks.beforeEach = cb; };

/**
 * Override the default no-op after() hook.
 *
 * @param {function} cb
 */
Describe.prototype.after = function(cb) { this.__hooks.after = cb; };

/**
 * Override the default no-op afterEach() hook.
 *
 * @param {function} cb
 */
Describe.prototype.afterEach = function(cb) { this.__hooks.afterEach = cb; };

/**
 * @param {string} name Test subject.
 * @param {function} cb
 */
function DescribeCallback(name, cb) {
  Bddflow.addInternalProp.call(this, 'name', name);
  this.cb = cb;
}

/**
 * Execute an array of functions w/ Batch.
 *
 * @param {array} steps
 * @param {function} cb Called at completion.
 * @param {number} [concurrency=1]
 */
function runSteps(steps, cb) {
  var batch = new Batch();
  batch.concurrency = 1;
  steps.forEach(function(step) { batch.push(step.cb); });
  batch.end(cb);
}

function noOp() {}
function batchNoOp(taskDone) { taskDone(); }
function defItWrap(name, cb) { cb(); }
<commit_msg>feat(Bddflow): Add 'describeWrap' setting<commit_after>/**
 * Build and run BDD flows with before/after hooks, describe, it
 *
 * Licensed under MIT.
 * Copyright (c) 2013 David Smith <https://github.com/codeactual/>
 */

/*jshint node:true*/
'use strict';

module.exports = {
  Bddflow: Bddflow,
  create: create,
  require: require // Allow tests to use component-land require.
};

var Batch = require('batch');
var bind = require('bind');
var clone = require('clone');
var configurable = require('configurable.js');
var extend = require('extend');

// Match properties that should not be 'inherited' by it(), hooks, or all.
var defOmitContextRegex = {
  all: [/^__|^(it|describe|before|beforeEach|after|afterEach|settings|set|get)$/],
  it: [],
  hook: []
};

function create() { return new Bddflow(); }

/**
 * Flow configuration and execution.
 */
function Bddflow() {
  this.settings = {
    done: noOp, // Batch#end callback that fires after flow completes.

    // Propagate to each new Describe instance:
    itWrap: null,
    describeWrap: null,
    omitContextRegex: clone(defOmitContextRegex),
    path: [], // Names of ancestor describe levels to the currently executing it().
    grep: /.?/, // Filters it() execution by "current path + it() name".
    grepv: null // Omits it() execution by "current path + it() name".
  };
  this.rootDescribes = [];
  this.batch = new Batch();
  this.seedProps = {}; // Will me merged into initial hook/describe/it context.
  this.running = false;
}
Bddflow.sharedConfigKeys = [
  'describeWrap', 'itWrap', 'omitContextRegex', 'path', 'grep', 'grepv'
];

configurable(Bddflow.prototype);

/**
 * Add a property to the initial hook/describe/it shared context.
 *
 * @param {string} key
 * @param {mixed} val
 * @return {object} this
 */
Bddflow.prototype.addContextProp = function(key, val) {
  this.seedProps[key] = val;
  return this;
};

/**
 * Add a top-level describe().
 *
 * @param {string} name
 * @param {function} cb
 */
Bddflow.prototype.addRootDescribe = function(name, cb) {
  var self = this;
  var desc = new Describe(name);

  var bddFlowConfig = {}; // Propagate selected settings.
  Bddflow.sharedConfigKeys.forEach(function(key) {
    bddFlowConfig[key] = self.get(key);
  });
  desc.set('bddFlowConfig', bddFlowConfig);

  desc.describe(name, cb);
  this.rootDescribes.push(desc);
  return this;
};

/**
 * Prevent a type of flow function from 'inheriting' specific context properties
 * from enclosing/subsequently-executed flow functions.
 *
 * @param {string} 'it', 'hook'
 * @param {object} RegExp instance.
 * @return {object} this
 */
Bddflow.prototype.hideContextProp = function(type, regex) {
  this.get('omitContextRegex')[type].push(regex);
  return this;
};

/**
 * Check if run() has been called.
 *
 * @return {boolean}
 */
Bddflow.prototype.isRunning = function() {
  return this.running;
};

/**
 * Run collected describe() layers.
 */
Bddflow.prototype.run = function() {
  var self = this;

  this.running = true;

  var batch = new Batch();
  batch.concurrency = 1;
  this.rootDescribes.forEach(function(desc) {
    batch.push(function(taskDone) {
      extend(desc, self.seedProps);
      runSteps(desc.__steps, taskDone);
    });
  });
  batch.end(this.get('done'));
};

/**
 * Filter 'this' into an object with properties that can be 'inherited'
 * between hooks/describe/it.
 *
 * Static used in other classes via call(). Exposed for test access.
 *
 * @param {string} type 'describe', 'it', 'hook'
 * @return {object}
 */
Bddflow.getInheritableContext = function(type) {
  var self = this;
  var omitContextRegex = this.get('bddFlowConfig').omitContextRegex;
  var regex = omitContextRegex.all.concat(type ? omitContextRegex[type] : []);

  return Object.keys(this).reduce(function(memo, key) {
    var omit = false;
    regex.forEach(function(re) {
      omit = omit || re.test(key);
    });
    if (omit) {
      return memo;
    }
    memo[key] = self[key];
    return memo;
  }, {});
};

/**
 * Augment 'this' with a new non-enumerable/configrable property intended
 * for internal-use only. Help avoid conflicts with properties 'inherited'
 * via getInheritableContext.
 *
 * Static used in other classes via call(). Exposed for test access.
 *
 * @param {string} key
 * @param {mixed} value
 */
Bddflow.addInternalProp = function(key, value) {
  Object.defineProperty(
    this, '__' + key,
    {value: value, enumerable: false, configurable: false, writable: true}
  );
};

/**
 * Callback context for before(), beforeEach(), etc.
 *
 * @param {string} name Of enclosing describe().
 */
function HookContext(name) {
  Bddflow.addInternalProp.call(this, 'name', name);
}
configurable(HookContext.prototype);
HookContext.prototype.getInheritableContext = Bddflow.getInheritableContext;

// Auto-terminating callback for use with Batch#push.
Bddflow.defaultHookImpl = function(done) { done(); };

/**
 * Container for a before(), beforeEach(), etc. method set.
 */
function HookSet() {
  this.before = Bddflow.defaultHookImpl;
  this.beforeEach = Bddflow.defaultHookImpl;
  this.after = Bddflow.defaultHookImpl;
  this.afterEach = Bddflow.defaultHookImpl;
}

/**
 * @param {string} name Subject expectation.
 * @param {string} name Test subject.
 */
function ItCallback(name, cb) {
  Bddflow.addInternalProp.call(this, 'name', name);
  this.cb = cb;
}

/**
 * A describe()'s properties, internal hooks, and nested steps (describe/it).
 *
 * @param {string} name Subject expected to exhibit some behavior.
 */
function Describe(name) {
  Bddflow.addInternalProp.call(this, 'name', name);
  Bddflow.addInternalProp.call(this, 'steps', []);
  Bddflow.addInternalProp.call(this, 'hooks', new HookSet());
  this.settings = {
    bddFlowConfig: {}
  };
}
configurable(Describe.prototype);
Describe.prototype.getInheritableContext = Bddflow.getInheritableContext;

/**
 * Add an it() step.
 *
 * @param {string} name
 * @param {function} cb Batch#push compat.
 */
Describe.prototype.it = function(name, cb) {
  this.__steps.push(new ItCallback(name, cb));
};

/**
 * Add a describe() step.
 *
 * @param {string} name
 * @param {function} cb Batch#push compat.
 */
Describe.prototype.describe = function(name, cb) {
  var self = this;
  var step = function(done) {
    var desc = new Describe(name); // Collect nested steps.
    var bddFlowConfig = clone(self.get('bddFlowConfig'));
    bddFlowConfig.path.push(name);
    desc.set('bddFlowConfig', bddFlowConfig);
    extend(desc, self.getInheritableContext());

    var describeWrap = self.get('bddFlowConfig').describeWrap || defDescribeWrap;
    describeWrap(name, function() {
      var wrapContext = this;
      var mergedContext = extend(desc, wrapContext);
      cb.call(mergedContext);
    });

    var hc = new HookContext(name);
    hc.set('bddFlowConfig', self.get('bddFlowConfig'));

    var batch = new Batch();

    batch.push(function(done) {
      extend(hc, desc.getInheritableContext('hook'));
      function asyncCb() {
        extend(desc, hc.getInheritableContext('hook'));
        done();
      }
      var hook = desc.__hooks.before;
      if (hook.length) { // Expects callback arg.
        desc.__hooks.before.call(hc, asyncCb);
      } else {
        desc.__hooks.before.call(hc);
        asyncCb();
      }
    });

    batch.push(function(done) { // Wrap hooks around each internal describe()/it()
      desc.__steps = desc.__steps.map(function(step) {
        if (step instanceof DescribeCallback) {
          extend(desc, hc.getInheritableContext());
          return new DescribeCallback(step.__name, bind(desc, step.cb));
        }

        var itPath = bddFlowConfig.path.concat(step.__name);
        if (bddFlowConfig.grepv) {
          if (bddFlowConfig.grepv.test(itPath.join(' '))) {
            return new ItCallback(step.__name, batchNoOp);
          }
        } else if (bddFlowConfig.grep) {
          if (!bddFlowConfig.grep.test(itPath.join(' '))) {
            return new ItCallback(step.__name, batchNoOp);
          }
        }

        return new DescribeCallback(step.__name, function(done) { // instanceof ItCallback
          var batch = new Batch();
          batch.push(function(done) {
            extend(hc, desc.getInheritableContext('hook'));
            function asyncCb() {
              extend(desc, hc.getInheritableContext('hook'));
              done();
            }
            var hook = desc.__hooks.beforeEach;
            if (hook.length) { // Expects callback arg.
              desc.__hooks.beforeEach.call(hc, asyncCb);
            } else {
              desc.__hooks.beforeEach.call(hc);
              asyncCb();
            }
          });
          batch.push(function(done) {
            var itContext = {};
            extend(itContext, desc.getInheritableContext('it'));
            itContext.__name = step.__name;
            itContext.__path = itPath;

            var itWrap = self.get('bddFlowConfig').itWrap || defItWrap;
            itWrap(step.__name, function() {
              var wrapContext = this;
              var mergedContext = extend(itContext, wrapContext);
              if (step.cb.length) { // Expects callback arg.
                step.cb.call(mergedContext, done);
              } else {
                step.cb.call(mergedContext);
                done();
              }
            });
          });
          batch.push(function(done) {
            function asyncCb() {
              extend(desc, hc.getInheritableContext('hook'));
              done();
            }
            var hook = desc.__hooks.afterEach;
            if (hook.length) { // Expects callback arg.
              desc.__hooks.afterEach.call(hc, asyncCb);
            } else {
              desc.__hooks.afterEach.call(hc);
              asyncCb();
            }
          });
          batch.concurrency = 1;
          batch.end(done);
        });
      });

      runSteps(desc.__steps, done);
    });

    batch.push(function(done) {
      extend(hc, desc.getInheritableContext('hook'));
      function asyncCb() {
        extend(desc, hc.getInheritableContext('hook'));
        done();
      }
      var hook = desc.__hooks.after;
      if (hook.length) { // Expects callback arg.
        desc.__hooks.after.call(hc, asyncCb);
      } else {
        desc.__hooks.after.call(hc);
        asyncCb();
      }
    });

    batch.concurrency = 1;
    batch.end(done);
  };
  this.__steps.push(new DescribeCallback(name, step));
};

/**
 * Override the default no-op before() hook.
 *
 * @param {function} cb
 */
Describe.prototype.before = function(cb) { this.__hooks.before = cb; };

/**
 * Override the default no-op beforeEach() hook.
 *
 * @param {function} cb
 */
Describe.prototype.beforeEach = function(cb) { this.__hooks.beforeEach = cb; };

/**
 * Override the default no-op after() hook.
 *
 * @param {function} cb
 */
Describe.prototype.after = function(cb) { this.__hooks.after = cb; };

/**
 * Override the default no-op afterEach() hook.
 *
 * @param {function} cb
 */
Describe.prototype.afterEach = function(cb) { this.__hooks.afterEach = cb; };

/**
 * @param {string} name Test subject.
 * @param {function} cb
 */
function DescribeCallback(name, cb) {
  Bddflow.addInternalProp.call(this, 'name', name);
  this.cb = cb;
}

/**
 * Execute an array of functions w/ Batch.
 *
 * @param {array} steps
 * @param {function} cb Called at completion.
 * @param {number} [concurrency=1]
 */
function runSteps(steps, cb) {
  var batch = new Batch();
  batch.concurrency = 1;
  steps.forEach(function(step) { batch.push(step.cb); });
  batch.end(cb);
}

function noOp() {}
function batchNoOp(taskDone) { taskDone(); }
function defItWrap(name, cb) { cb(); }
function defDescribeWrap(name, cb) { cb(); }
<|endoftext|>


<commit_before>import dateField from './DateField'
import mapField from './MapField'
import suggestField from './SuggestField'

export const DateField = dateField
export const MapField = mapField
export const SuggestField = suggestField<commit_msg>Temporary disable map field and suggest field<commit_after>import dateField from './DateField'
import mapField from './MapField'
import suggestField from './SuggestField'

export const DateField = dateField
// export const MapField = mapField
// export const SuggestField = suggestField<|endoftext|>