<commit_before>"use strict";
var mocha = require('gulp-mocha'),
    Q = require('q'),
    globby = Q.denodeify(require('globby')),
    Transpiler = require('../index').Transpiler,
    jshint = require('gulp-jshint'),
    jscs = require('gulp-jscs'),
    vinylPaths = require('vinyl-paths'),
    del = require('del'),
    _ = require('lodash'),
    promisePipe = require("promisepipe"),
    AndroidEmulator = require('appium-ci').AndroidEmulator,
    androidTools = require('appium-ci').androidTools,
    iosTools = require('appium-ci').iosTools,
    spawn = require('child_process').spawn,
    exec = Q.denodeify(require('child_process').exec),
    path = require('path');

var DEFAULT_OPTS = {
  files: ["*.js", "lib/**/*.js", "test/**/*.js", "!gulpfile.js"],
  transpile: true,
  transpileOut: "build",
  babelOpts: {},
  linkBabelRuntime: true,
  jscs: false,
  jshint: true,
  watch: true,
  watchE2E: false,
  test: {
    files: ['${testDir}/**/*-specs.js', '!${testDir}/**/*-e2e-specs.js']
  },
  coverage: {
    files: ['./test/**/*-specs.js', '!./test/**/*-e2e-specs.js'],
    verbose: true
   },
  e2eTest: {
    files: '${testDir}/**/*-e2e-specs.js'
  },
  testReporter: ( process.env.TRAVIS || process.env.CI ) ? 'spec' : 'nyan',
  testTimeout: 8000,
  buildName: null,
};

// string interpolation
var interpolate = function (s, opts) {
  return _.keys(opts).reduce(function (s, k) {
    return s.replace(new RegExp('\\$\\{\\s*' + k + '\\s*\\}', 'g') , opts[k]);
  } , s);
};

var boilerplate = function (gulp, opts) {
  var spawnWatcher = require('../index').spawnWatcher.use(gulp);
  var runSequence = Q.denodeify(require('run-sequence').use(gulp));
  var defOpts = _.clone(DEFAULT_OPTS);
  _.extend(defOpts, opts);
  opts = defOpts;

  process.env.APPIUM_NOTIF_BUILD_NAME = opts.buildName;

  gulp.task('clean', function () {
    if (opts.transpile) {
      return gulp.src(opts.transpileOut, {read: false})
                 .pipe(vinylPaths(del));
    }
  });

  var testDeps = [];
  var testTasks = [];
  var rootDir = '.';
  if (opts.transpile) {
    testDeps.push('transpile');
    rootDir = opts.transpileOut;
  }
  var fileAliases = {rootDir: rootDir, testDir: rootDir + '/test', libDir: rootDir + '/lib' };

  if (opts.test) {
    var testFiles = _.flatten([opts.test.files || opts.testFiles]).map(function (f) {
      return interpolate(f, fileAliases);
    });
    gulp.task('unit-test', testDeps,  function () {
      var isForceLogMode = parseInt(process.env._FORCE_LOGS, 10) === 1;
      var mochaOpts = {
        reporter: isForceLogMode ? 'spec' : opts.testReporter,
        timeout: opts.testTimeout
      };
      // set env so our code knows when it's being run in a test env
      process.env._TESTING = 1;
      return gulp
       .src(testFiles, {read: false})
       .pipe(mocha(mochaOpts))
       .on('error', spawnWatcher.handleError);
    });
    testTasks.push('unit-test');
  }

  if (opts.coverage) {
    var covTestFiles = _.flatten([opts.coverage.files]).map(function (f) {
      return interpolate(f, fileAliases);
    });
    gulp.task('coverage', function () {
      return exec('rm -rf ./build').then(function () {
        return globby(covTestFiles).then(function (files) {
          var deferred = Q.defer();
          var bins = {};
          _.each(['isparta', '--report', 'text', '_mocha'], function (k) { bins[k] = path.resolve(__dirname, '../node_modules/.bin', k); });
          var bin = bins.isparta;
          var args = ['cover', bins._mocha, '--', '--require', __dirname + '/../babelhook', '--compilers', 'babel:babel/register' , '--reporter', 'dot']
            .concat(files);
          var env = _.clone(process.env);
          env.NO_PRECOMPILE=1;
          env._TESTING=1;
          console.log("running command -->", bin, args.join(' '));
          var proc = spawn(bin, args, {stdio: opts.coverage.verbose ? 'inherit' : 'ignore', env: env});
          proc.on('close', function (code) {
            if (code === 0) {
              deferred.resolve();
            } else {
              deferred.reject(new Error('Coverage command exit code: ' + code));
            }
          });
          return deferred.promise;
        });
      }).catch(spawnWatcher.handleError);
    });
    gulp.task('coveralls', ['coverage'], function () {
      var bin = path.resolve(__dirname, '../node_modules/.bin/coveralls');
      return exec('cat ./coverage/lcov.info | ' + bin).catch(spawnWatcher.handleError);
    });
  }

  if (opts.e2eTest) {
    var e2eTestFiles = _.flatten([opts.e2eTest.files || opts.e2eTestFiles]).map(function (f) {
      return interpolate(f, fileAliases);
    });
    gulp.task('e2e-test', testDeps,  function () {
      var isForceLogMode = parseInt(process.env._FORCE_LOGS, 10) === 1;
      var mochaOpts = {
        reporter: isForceLogMode ? 'spec' : opts.testReporter,
        timeout: opts.testTimeout
      };
      // set env so our code knows when it's being run in a test env
      process.env._TESTING = 1;
      var seq = [
        function () {
          return promisePipe(gulp
           .src(e2eTestFiles, {read: false})
           .pipe(mocha(mochaOpts))
           .on('error', spawnWatcher.handleError));
        }];
      if (opts.e2eTest.android) {
        var emu = new AndroidEmulator(opts.e2eTest.avd);
        seq = [
          function () { return androidTools.killAll(); },
          function () {
            emu.start();
            return emu.waitTillReady();
          }].concat(seq).concat([
            function () { return emu.stop(); },
            function () { return androidTools.killAll(); }
          ]);
      }
      if (opts.e2eTest.ios) {
        var xCodeVersion = opts.e2eTest.xCodeVersion || '6.1.1';
        seq = [
          function () { return iosTools.killAll(); },
          function () { return iosTools.configureXcode(xCodeVersion); },
          function () { return iosTools.resetSims(); },
        ].concat(seq).concat([
          function () { return iosTools.killAll(); }
        ]);
      }
      return seq.reduce(Q.when, new Q()).catch(spawnWatcher.handleError);
    });
    testTasks.push('e2e-test');
  }

  if (testTasks.length > 0) {
    gulp.task('test', function () {
      return runSequence(testTasks);
    });
  }

  if (opts.transpile) {
    gulp.task('transpile', function () {
      var transpiler = new Transpiler(opts.babelOpts);
      return gulp.src(opts.files, {base: './'})
        .pipe(transpiler.stream())
        .on('error', spawnWatcher.handleError)
        .pipe(gulp.dest(opts.transpileOut));
    });

    gulp.task('prepublish', function () {
      return runSequence('clean', 'transpile');
    });
  }

  var lintTasks = [];
  if (opts.jscs) {
    gulp.task('jscs', function () {
      return gulp
       .src(opts.files)
       .pipe(jscs())
       .on('error', spawnWatcher.handleError);
    });
    lintTasks.push('jscs');
  }

  if (opts.jshint) {
    gulp.task('jshint', function () {
      return gulp
       .src(opts.files)
       .pipe(jshint())
       .pipe(jshint.reporter('jshint-stylish'))
       .pipe(jshint.reporter('fail'))
       .on('error', spawnWatcher.handleError);
    });
    lintTasks.push('jshint');
  }

  if (opts.jscs || opts.jshint) {
    opts.lint = true;
    gulp.task('lint', lintTasks);
  }

  var defaultSequence = [];
  if (opts.transpile) defaultSequence.push('clean');
  if (opts.lint) defaultSequence.push('lint');
  if (opts.transpile && !opts.test) defaultSequence.push('transpile');
  if (opts.test) {
    if (opts.watchE2E) {
      defaultSequence.push('test');
    } else if (_.contains(testTasks, 'unit-test')) {
      defaultSequence.push('unit-test');
    }
  }
  if (opts.extraDefaultTasks) defaultSequence = defaultSequence.concat(opts.extraDefaultTasks);

  if (opts.watch) {
    spawnWatcher.clear(false);
    spawnWatcher.configure('watch', opts.files, function () {
      return runSequence.apply(null, defaultSequence);
    });
  }

  gulp.task('once', function () {
    return runSequence.apply(null, defaultSequence);
  });

  gulp.task('default', [opts.watch ? 'watch' : 'once']);
};

module.exports = {
  DEFAULTS: _.cloneDeep(DEFAULT_OPTS),
  use: function (gulp) {
    return function (opts) {
      boilerplate(gulp, opts);
    };
  }
};
<commit_msg>runSequence expects args, not an array<commit_after>"use strict";
var mocha = require('gulp-mocha'),
    Q = require('q'),
    globby = Q.denodeify(require('globby')),
    Transpiler = require('../index').Transpiler,
    jshint = require('gulp-jshint'),
    jscs = require('gulp-jscs'),
    vinylPaths = require('vinyl-paths'),
    del = require('del'),
    _ = require('lodash'),
    promisePipe = require("promisepipe"),
    AndroidEmulator = require('appium-ci').AndroidEmulator,
    androidTools = require('appium-ci').androidTools,
    iosTools = require('appium-ci').iosTools,
    spawn = require('child_process').spawn,
    exec = Q.denodeify(require('child_process').exec),
    path = require('path');

var DEFAULT_OPTS = {
  files: ["*.js", "lib/**/*.js", "test/**/*.js", "!gulpfile.js"],
  transpile: true,
  transpileOut: "build",
  babelOpts: {},
  linkBabelRuntime: true,
  jscs: false,
  jshint: true,
  watch: true,
  watchE2E: false,
  test: {
    files: ['${testDir}/**/*-specs.js', '!${testDir}/**/*-e2e-specs.js']
  },
  coverage: {
    files: ['./test/**/*-specs.js', '!./test/**/*-e2e-specs.js'],
    verbose: true
   },
  e2eTest: {
    files: '${testDir}/**/*-e2e-specs.js'
  },
  testReporter: ( process.env.TRAVIS || process.env.CI ) ? 'spec' : 'nyan',
  testTimeout: 8000,
  buildName: null,
};

// string interpolation
var interpolate = function (s, opts) {
  return _.keys(opts).reduce(function (s, k) {
    return s.replace(new RegExp('\\$\\{\\s*' + k + '\\s*\\}', 'g') , opts[k]);
  } , s);
};

var boilerplate = function (gulp, opts) {
  var spawnWatcher = require('../index').spawnWatcher.use(gulp);
  var runSequence = Q.denodeify(require('run-sequence').use(gulp));
  var defOpts = _.clone(DEFAULT_OPTS);
  _.extend(defOpts, opts);
  opts = defOpts;

  process.env.APPIUM_NOTIF_BUILD_NAME = opts.buildName;

  gulp.task('clean', function () {
    if (opts.transpile) {
      return gulp.src(opts.transpileOut, {read: false})
                 .pipe(vinylPaths(del));
    }
  });

  var testDeps = [];
  var testTasks = [];
  var rootDir = '.';
  if (opts.transpile) {
    testDeps.push('transpile');
    rootDir = opts.transpileOut;
  }
  var fileAliases = {rootDir: rootDir, testDir: rootDir + '/test', libDir: rootDir + '/lib' };

  if (opts.test) {
    var testFiles = _.flatten([opts.test.files || opts.testFiles]).map(function (f) {
      return interpolate(f, fileAliases);
    });
    gulp.task('unit-test', testDeps,  function () {
      var isForceLogMode = parseInt(process.env._FORCE_LOGS, 10) === 1;
      var mochaOpts = {
        reporter: isForceLogMode ? 'spec' : opts.testReporter,
        timeout: opts.testTimeout
      };
      // set env so our code knows when it's being run in a test env
      process.env._TESTING = 1;
      return gulp
       .src(testFiles, {read: false})
       .pipe(mocha(mochaOpts))
       .on('error', spawnWatcher.handleError);
    });
    testTasks.push('unit-test');
  }

  if (opts.coverage) {
    var covTestFiles = _.flatten([opts.coverage.files]).map(function (f) {
      return interpolate(f, fileAliases);
    });
    gulp.task('coverage', function () {
      return exec('rm -rf ./build').then(function () {
        return globby(covTestFiles).then(function (files) {
          var deferred = Q.defer();
          var bins = {};
          _.each(['isparta', '--report', 'text', '_mocha'], function (k) { bins[k] = path.resolve(__dirname, '../node_modules/.bin', k); });
          var bin = bins.isparta;
          var args = ['cover', bins._mocha, '--', '--require', __dirname + '/../babelhook', '--compilers', 'babel:babel/register' , '--reporter', 'dot']
            .concat(files);
          var env = _.clone(process.env);
          env.NO_PRECOMPILE=1;
          env._TESTING=1;
          console.log("running command -->", bin, args.join(' '));
          var proc = spawn(bin, args, {stdio: opts.coverage.verbose ? 'inherit' : 'ignore', env: env});
          proc.on('close', function (code) {
            if (code === 0) {
              deferred.resolve();
            } else {
              deferred.reject(new Error('Coverage command exit code: ' + code));
            }
          });
          return deferred.promise;
        });
      }).catch(spawnWatcher.handleError);
    });
    gulp.task('coveralls', ['coverage'], function () {
      var bin = path.resolve(__dirname, '../node_modules/.bin/coveralls');
      return exec('cat ./coverage/lcov.info | ' + bin).catch(spawnWatcher.handleError);
    });
  }

  if (opts.e2eTest) {
    var e2eTestFiles = _.flatten([opts.e2eTest.files || opts.e2eTestFiles]).map(function (f) {
      return interpolate(f, fileAliases);
    });
    gulp.task('e2e-test', testDeps,  function () {
      var isForceLogMode = parseInt(process.env._FORCE_LOGS, 10) === 1;
      var mochaOpts = {
        reporter: isForceLogMode ? 'spec' : opts.testReporter,
        timeout: opts.testTimeout
      };
      // set env so our code knows when it's being run in a test env
      process.env._TESTING = 1;
      var seq = [
        function () {
          return promisePipe(gulp
           .src(e2eTestFiles, {read: false})
           .pipe(mocha(mochaOpts))
           .on('error', spawnWatcher.handleError));
        }];
      if (opts.e2eTest.android) {
        var emu = new AndroidEmulator(opts.e2eTest.avd);
        seq = [
          function () { return androidTools.killAll(); },
          function () {
            emu.start();
            return emu.waitTillReady();
          }].concat(seq).concat([
            function () { return emu.stop(); },
            function () { return androidTools.killAll(); }
          ]);
      }
      if (opts.e2eTest.ios) {
        var xCodeVersion = opts.e2eTest.xCodeVersion || '6.1.1';
        seq = [
          function () { return iosTools.killAll(); },
          function () { return iosTools.configureXcode(xCodeVersion); },
          function () { return iosTools.resetSims(); },
        ].concat(seq).concat([
          function () { return iosTools.killAll(); }
        ]);
      }
      return seq.reduce(Q.when, new Q()).catch(spawnWatcher.handleError);
    });
    testTasks.push('e2e-test');
  }

  if (testTasks.length > 0) {
    gulp.task('test', function () {
      return runSequence.apply(null, testTasks);
    });
  }

  if (opts.transpile) {
    gulp.task('transpile', function () {
      var transpiler = new Transpiler(opts.babelOpts);
      return gulp.src(opts.files, {base: './'})
        .pipe(transpiler.stream())
        .on('error', spawnWatcher.handleError)
        .pipe(gulp.dest(opts.transpileOut));
    });

    gulp.task('prepublish', function () {
      return runSequence('clean', 'transpile');
    });
  }

  var lintTasks = [];
  if (opts.jscs) {
    gulp.task('jscs', function () {
      return gulp
       .src(opts.files)
       .pipe(jscs())
       .on('error', spawnWatcher.handleError);
    });
    lintTasks.push('jscs');
  }

  if (opts.jshint) {
    gulp.task('jshint', function () {
      return gulp
       .src(opts.files)
       .pipe(jshint())
       .pipe(jshint.reporter('jshint-stylish'))
       .pipe(jshint.reporter('fail'))
       .on('error', spawnWatcher.handleError);
    });
    lintTasks.push('jshint');
  }

  if (opts.jscs || opts.jshint) {
    opts.lint = true;
    gulp.task('lint', lintTasks);
  }

  var defaultSequence = [];
  if (opts.transpile) defaultSequence.push('clean');
  if (opts.lint) defaultSequence.push('lint');
  if (opts.transpile && !opts.test) defaultSequence.push('transpile');
  if (opts.test) {
    if (opts.watchE2E) {
      defaultSequence.push('test');
    } else if (_.contains(testTasks, 'unit-test')) {
      defaultSequence.push('unit-test');
    }
  }
  if (opts.extraDefaultTasks) defaultSequence = defaultSequence.concat(opts.extraDefaultTasks);

  if (opts.watch) {
    spawnWatcher.clear(false);
    spawnWatcher.configure('watch', opts.files, function () {
      return runSequence.apply(null, defaultSequence);
    });
  }

  gulp.task('once', function () {
    return runSequence.apply(null, defaultSequence);
  });

  gulp.task('default', [opts.watch ? 'watch' : 'once']);
};

module.exports = {
  DEFAULTS: _.cloneDeep(DEFAULT_OPTS),
  use: function (gulp) {
    return function (opts) {
      boilerplate(gulp, opts);
    };
  }
};
<|endoftext|>


<commit_before>

var execSync = require('child_process').execSync;
var path = require('path');

var bin = path.join(__dirname, './../bin/kebot');

test('argument miss', () => {
    let command = execSync(`$(which node) ${bin} task:args-miss -t`);

    expect(command.toString().split('\n').slice(1).join('')).toEqual('execute task');
});

test('argument contain "args" in flag --args', () => {
    let command = execSync(`$(which node) ${bin} task:args  --args args -t`);

    expect(command.toString().split('\n').slice(1).join('')).toEqual('args');
});

test('argument environment in flag --env', () => {
    let command = execSync(`$(which node) ${bin} task:env  --env production -t`);
    expect(command.toString().split('\n').slice(1).join('')).toEqual('true');
});

test('arguments multiples flags "--email" and "--template"', () => {
    const command = execSync(`$(which node) ${bin} task:args-multiple  --email juanpablocs21@gmail.com --template register-action -t`);
    const expected = ['juanpablocs21@gmail.com', 'register-action'];

    expect(command.toString().split('\n').slice(1)).toEqual(expect.arrayContaining(expected));
});
<commit_msg>test(kebot test): se hacen pruebas para exec y execSync<commit_after>

var exec = require('child_process').exec;
var execSync = require('child_process').execSync;

var path = require('path');

var bin = path.join(__dirname, './../bin/kebot');

test('argument miss', (done) => {
    exec(`node ${bin} task:args-miss -t`, (err, stdout)=>{
        expect(stdout.toString().split('\n').slice(1).join('')).toEqual('execute task');
        done();
    });
});

test('argument contain "args" in flag --args', () => {
    let command = execSync(`$(which node) ${bin} task:args  --args args -t`);

    expect(command.toString().split('\n').slice(1).join('')).toEqual('args');
});

test('argument environment in flag --env', () => {
    let command = execSync(`$(which node) ${bin} task:env  --env production -t`);
    expect(command.toString().split('\n').slice(1).join('')).toEqual('true');
});

test('arguments multiples flags "--email" and "--template"', () => {
    const command = execSync(`$(which node) ${bin} task:args-multiple  --email juanpablocs21@gmail.com --template register-action -t`);
    const expected = ['juanpablocs21@gmail.com', 'register-action'];

    expect(command.toString().split('\n').slice(1)).toEqual(expect.arrayContaining(expected));
});
<|endoftext|>


<commit_before>import PureRender from "react-addons-pure-render-mixin";
import PropTypes from "prop-types";
import React from "react";

import ConfigurationMapHeading from "./ConfigurationMapHeading";
import ConfigurationMapLabel from "./ConfigurationMapLabel";
import ConfigurationMapRow from "./ConfigurationMapRow";
import ConfigurationMapSection from "./ConfigurationMapSection";
import ConfigurationMapValue from "./ConfigurationMapValue";

class HashMapDisplay extends React.Component {
  constructor() {
    super(...arguments);
    this.shouldComponentUpdate = PureRender.shouldComponentUpdate.bind(this);
  }

  getHeadline() {
    const { headline, headlineClassName, headingLevel } = this.props;
    if (!headline) {
      return null;
    }

    // Wrap in headline element and classes
    return (
      <ConfigurationMapHeading
        className={headlineClassName}
        level={headingLevel}
      >
        {headline}
      </ConfigurationMapHeading>
    );
  }

  getItems() {
    const { hash, headingLevel, renderKeys, emptyValue } = this.props;

    return Object.keys(hash).map((key, index) => {
      let value = hash[key];

      // Check whether we are trying to render an object that is not a
      // React component
      if (
        typeof value === "object" &&
        !Array.isArray(value) &&
        value !== null &&
        !React.isValidElement(value)
      ) {
        // Increase the heading level for each nested description list,
        // ensuring we don't surpass heading level <h6/>.
        const nextHeadingLevel = Math.min(headingLevel + 1, 6);

        return (
          <HashMapDisplay
            {...this.props}
            hash={value}
            headingLevel={nextHeadingLevel}
            key={index}
            headline={key}
          />
        );
      }

      if (typeof value === "boolean") {
        value = value.toString();
      }

      if (Array.isArray(value)) {
        value = value.join(", ");
      }

      if (!value && emptyValue) {
        value = emptyValue;
      }

      // Check if we need to render a component in the dt
      if (Object.prototype.hasOwnProperty.call(renderKeys, key)) {
        key = renderKeys[key];
      }

      const isAttribute = this.props.headline === "Attributes";

      return (
        <ConfigurationMapRow key={index}>
          <ConfigurationMapLabel keepTextCase={isAttribute}>
            {key}
          </ConfigurationMapLabel>
          <ConfigurationMapValue>{value}</ConfigurationMapValue>
        </ConfigurationMapRow>
      );
    });
  }

  render() {
    const { hash } = this.props;
    if (!hash || Object.keys(hash).length === 0) {
      return null;
    }

    return (
      <ConfigurationMapSection>
        {this.getHeadline()}
        {this.getItems()}
      </ConfigurationMapSection>
    );
  }
}

HashMapDisplay.defaultProps = {
  headingLevel: 1,
  renderKeys: {}
};

HashMapDisplay.propTypes = {
  headingLevel: PropTypes.oneOf([1, 2, 3, 4, 5, 6]),
  headlineClassName: PropTypes.string,
  headline: PropTypes.node,
  hash: PropTypes.object,
  // Optional object with keys consisting of keys in `props.hash` to be
  // replaced, and with corresponding values of the replacement to be rendered.
  renderKeys: PropTypes.object,
  emptyValue: PropTypes.string
};

module.exports = HashMapDisplay;
<commit_msg>refactor(HashMapDisplay): complexity<commit_after>import PureRender from "react-addons-pure-render-mixin";
import PropTypes from "prop-types";
import React from "react";

import ConfigurationMapHeading from "./ConfigurationMapHeading";
import ConfigurationMapLabel from "./ConfigurationMapLabel";
import ConfigurationMapRow from "./ConfigurationMapRow";
import ConfigurationMapSection from "./ConfigurationMapSection";
import ConfigurationMapValue from "./ConfigurationMapValue";

const METHODS_TO_BIND = ["formatValue", "isHashMap"];

class HashMapDisplay extends React.Component {
  constructor() {
    super(...arguments);
    this.shouldComponentUpdate = PureRender.shouldComponentUpdate.bind(this);

    METHODS_TO_BIND.forEach(method => {
      this[method] = this[method].bind(this);
    });
  }

  getHeadline() {
    const { headline, headlineClassName, headingLevel } = this.props;
    if (!headline) {
      return null;
    }

    // Wrap in headline element and classes
    return (
      <ConfigurationMapHeading
        className={headlineClassName}
        level={headingLevel}
      >
        {headline}
      </ConfigurationMapHeading>
    );
  }

  getHashMapDisplay(headline, hashMap) {
    // Increase the heading level for each nested description list,
    // ensuring we don't surpass heading level <h6/>.
    const nextHeadingLevel = Math.min(this.props.headingLevel + 1, 6);

    return (
      <HashMapDisplay
        {...this.props}
        hash={hashMap}
        headingLevel={nextHeadingLevel}
        key={`hash-map-${headline}`}
        headline={headline}
      />
    );
  }

  getItemRow(headline, value) {
    const isAttribute = this.props.headline === "Attributes";

    return (
      <ConfigurationMapRow key={`hash-map-value-${headline}`}>
        <ConfigurationMapLabel keepTextCase={isAttribute}>
          {headline}
        </ConfigurationMapLabel>
        <ConfigurationMapValue>{this.formatValue(value)}</ConfigurationMapValue>
      </ConfigurationMapRow>
    );
  }

  getItems() {
    const { hash, renderKeys } = this.props;

    return Object.keys(hash).map(key => {
      const value = hash[key];

      if (this.isHashMap(value)) {
        return this.getHashMapDisplay(key, value);
      }

      // Check if we need to render a component in the dt
      if (Object.prototype.hasOwnProperty.call(renderKeys, key)) {
        key = renderKeys[key];
      }

      return this.getItemRow(key, value);
    });
  }

  render() {
    const { hash } = this.props;

    if (!hash || Object.keys(hash).length === 0) {
      return null;
    }

    return (
      <ConfigurationMapSection>
        {this.getHeadline()}
        {this.getItems()}
      </ConfigurationMapSection>
    );
  }

  formatValue(value) {
    if (typeof value === "boolean") {
      value = value.toString();
    }

    if (Array.isArray(value)) {
      value = value.join(", ");
    }

    if (!value && this.props.emptyValue) {
      value = this.props.emptyValue;
    }

    return value;
  }

  isHashMap(value) {
    // Check whether we are trying to render an object that is not a
    // React component

    return (
      typeof value === "object" &&
      !Array.isArray(value) &&
      value !== null &&
      !React.isValidElement(value)
    );
  }
}

HashMapDisplay.defaultProps = {
  headingLevel: 1,
  renderKeys: {}
};

HashMapDisplay.propTypes = {
  headingLevel: PropTypes.oneOf([1, 2, 3, 4, 5, 6]),
  headlineClassName: PropTypes.string,
  headline: PropTypes.node,
  hash: PropTypes.object,
  // Optional object with keys consisting of keys in `props.hash` to be
  // replaced, and with corresponding values of the replacement to be rendered.
  renderKeys: PropTypes.object,
  emptyValue: PropTypes.string
};

module.exports = HashMapDisplay;
<|endoftext|>


<commit_before>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

(function() {
    // special patch to correctly work on Ripple emulator (CB-9760)
    if (window.parent && !!window.parent.ripple) { // https://gist.github.com/triceam/4658021
        module.exports = window.open.bind(window); // fallback to default window.open behaviour
        return;
    }

    var exec = require('cordova/exec');
    var channel = require('cordova/channel');
    var modulemapper = require('cordova/modulemapper');
    var urlutil = require('cordova/urlutil');

    var unhideState = {
        polling:{
            interval: null,
            function: null,
        },
        eventHandlers : {

        },
        clearPolling: {
            unhideState.poll.interval = null;
            unhideState.interval.function = null;
        },
        clear: function(){
            this.clearPolling();
            unhideState.eventHandlers = {};
        },
        addEventHandler: function(eventname, eventHandlers){
            // if(!eventHandlers[eventname]) {
            //     eventHandlers[eventname] = {};
            // }
        }
    };

    function InAppBrowser() {
       this.channels = {
            'loadstart': channel.create('loadstart'),
            'loadstop' : channel.create('loadstop'),
            'loaderror' : channel.create('loaderror'),
            'hidden' : channel.create('hidden'),
            'unhidden' : channel.create('unhidden'),
            'pollresult' : channel.create('pollresult'),
            'exit' : channel.create('exit')
       };
    }

    InAppBrowser.prototype = {
        _eventHandler: function (event) {
            if (event && (event.type in this.channels)) {
                this.channels[event.type].fire(event);
            }
        },
        close: function (eventname) {
            unhideState.clear();
            exec(null, null, "InAppBrowser", "close", []);
        },
        show: function (eventname) {
          exec(null, null, "InAppBrowser", "show", []);
        },
        startPoll(pollingFunction, pollInterval){
            unhideState.poll.function = pollingFunction;
            unhideState.poll.interval = pollInterval;

            exec(null, null, "InAppBrowser", "startPoll", [pollingFunction, pollInterval])
        },
        stopPoll(){
            unhideState.clearPolling();
            exec(null, null, "InAppBrowser", "stopPoll", [])
        },
        hide: function(releaseResources, eventname){
            //TODO: intercept exit
            //TODO: hide.
            // if(boolGoToBlank){
            //     unhideState.clear();
            // }
            exec(null,null,"InAppBrowser", "hide", [boolGoToBlank]);
        },
        unHide: function(strUrl, eventname){
            console.log('+++++++++++++++++++++++++++++++++++++++++');
            console.log('TODO!!!!');
            console.log('+++++++++++++++++++++++++++++++++++++++++');
            //exec(null,null,"InAppBrowser", "unHide", [strUrl]);
        },
        addEventListener: function (eventname,f) {
            if (eventname in this.channels) {
                this.channels[eventname].subscribe(f);
                console.log(f);
            }
        },
        removeEventListener: function(eventname, f) {
            if (eventname in this.channels) {
                this.channels[eventname].unsubscribe(f);
            }
        },

        executeScript: function(injectDetails, cb) {
            if (injectDetails.code) {
                exec(cb, null, "InAppBrowser", "injectScriptCode", [injectDetails.code, !!cb]);
            } else if (injectDetails.file) {
                exec(cb, null, "InAppBrowser", "injectScriptFile", [injectDetails.file, !!cb]);
            } else {
                throw new Error('executeScript requires exactly one of code or file to be specified');
            }
        },

        insertCSS: function(injectDetails, cb) {
            if (injectDetails.code) {
                exec(cb, null, "InAppBrowser", "injectStyleCode", [injectDetails.code, !!cb]);
            } else if (injectDetails.file) {
                exec(cb, null, "InAppBrowser", "injectStyleFile", [injectDetails.file, !!cb]);
            } else {
                throw new Error('insertCSS requires exactly one of code or file to be specified');
            }
        }
    };

    module.exports = function(strUrl, strWindowName, strWindowFeatures, callbacks) {
        // Don't catch calls that write to existing frames (e.g. named iframes).
        if (window.frames && window.frames[strWindowName]) {
            var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open');
            return origOpenFunc.apply(window, arguments);
        }

        strUrl = urlutil.makeAbsolute(strUrl);
        var iab = new InAppBrowser();

        callbacks = callbacks || {};
        for (var callbackName in callbacks) {
            iab.addEventListener(callbackName, callbacks[callbackName]);
        }

        var cb = function(eventname) {
           iab._eventHandler(eventname);
        };

        strWindowFeatures = strWindowFeatures || "";

        exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
        return iab;
    };
})();
<commit_msg>medium refactor of js code<commit_after>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

(function() {
    // special patch to correctly work on Ripple emulator (CB-9760)
    if (window.parent && !!window.parent.ripple) { // https://gist.github.com/triceam/4658021
        module.exports = window.open.bind(window); // fallback to default window.open behaviour
        return;
    }

    var exec = require('cordova/exec');
    var channel = require('cordova/channel');
    var modulemapper = require('cordova/modulemapper');
    var urlutil = require('cordova/urlutil');

    var InAppBrowser = function() {

        var eventHandlers: {},
            lastPollInterval: null,
            lastPollFunction: null,
            clearPolling: function {
                polling.pollInterval = null;
                polling.pollFunction = null;
            },
            clear = function(){
                this.clearPolling();
                unhideState.eventHandlers = {};
            };

        this.channels = {
            'loadstart': channel.create('loadstart'),
            'loadstop' : channel.create('loadstop'),
            'loaderror' : channel.create('loaderror'),
            'hidden' : channel.create('hidden'),
            'unhidden' : channel.create('unhidden'),
            'pollresult' : channel.create('pollresult'),
            'exit' : channel.create('exit')
        }

        this._eventHandler = function (event) {
            if (event && (event.type in this.channels)) {
               this.channels[event.type].fire(event);
            }
        }

        this.close = function (eventname) {
           clear();
           exec(null, null, "InAppBrowser", "close", []);
        }

        this.show = function (eventname) {
            exec(null, null, "InAppBrowser", "show", []);
        }

        this.startPoll(pollFunction, pollInterval){
           lastPollInterval = pollInterval;
           lastPollFunction = pollFunction;
           exec(null, null, "InAppBrowser", "startPoll", [pollFunction, pollInterval])
        }

        this.stopPoll(){
           clearPolling();
           exec(null, null, "InAppBrowser", "stopPoll", [])
        }

        this.hide = function(releaseResources, eventname){
            //TODO: intercept exit
            //TODO: hide.
            // if(boolGoToBlank){
            //     unhideState.clear();
            // }
            exec(null,null,"InAppBrowser", "hide", [boolGoToBlank]);
        }

        this.unHide = function(strUrl, eventname){
            console.log('+++++++++++++++++++++++++++++++++++++++++');
            console.log('TODO!!!!');
            console.log('+++++++++++++++++++++++++++++++++++++++++');
            //exec(null,null,"InAppBrowser", "unHide", [strUrl]);
        }

        this.addEventListener = function (eventname,f) {
            if (eventname in this.channels) {
                this.channels[eventname].subscribe(f);
                console.log(f);
                console.log('TODO: Add Event Handler');
            }
        }

        this.removeEventListener = function(eventname, f) {
            if (eventname in this.channels) {
                this.channels[eventname].unsubscribe(f);
                console.log('TODO: Add Remove Handler');

            }
        }

        this.executeScript = function(injectDetails, cb) {
            if (injectDetails.code) {
                exec(cb, null, "InAppBrowser", "injectScriptCode", [injectDetails.code, !!cb]);
            } else if (injectDetails.file) {
                exec(cb, null, "InAppBrowser", "injectScriptFile", [injectDetails.file, !!cb]);
            } else {
                throw new Error('executeScript requires exactly one of code or file to be specified');
            }
        }

        this.insertCSS = function(injectDetails, cb) {
            if (injectDetails.code) {
                exec(cb, null, "InAppBrowser", "injectStyleCode", [injectDetails.code, !!cb]);
            } else if (injectDetails.file) {
                exec(cb, null, "InAppBrowser", "injectStyleFile", [injectDetails.file, !!cb]);
            } else {
                throw new Error('insertCSS requires exactly one of code or file to be specified');
            }
        }
    }

    module.exports = function(strUrl, strWindowName, strWindowFeatures, callbacks) {
        // Don't catch calls that write to existing frames (e.g. named iframes).
        if (window.frames && window.frames[strWindowName]) {
            var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open');
            return origOpenFunc.apply(window, arguments);
        }

        strUrl = urlutil.makeAbsolute(strUrl);
        var iab = new InAppBrowser();

        callbacks = callbacks || {};
        for (var callbackName in callbacks) {
            iab.addEventListener(callbackName, callbacks[callbackName]);
        }

        var cb = function(eventname) {
           iab._eventHandler(eventname);
        };

        strWindowFeatures = strWindowFeatures || "";

        exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
        return iab;
    };
})();
<|endoftext|>


<commit_before>"use strict";
var mocha = require('gulp-mocha'),
    Q = require('q'),
    globby = Q.denodeify(require('globby')),
    Transpiler = require('../index').Transpiler,
    jshint = require('gulp-jshint'),
    jscs = require('gulp-jscs'),
    vinylPaths = require('vinyl-paths'),
    del = require('del'),
    _ = require('lodash'),
    promisePipe = require("promisepipe"),
    AndroidEmulator = require('appium-ci').AndroidEmulator,
    androidTools = require('appium-ci').androidTools,
    iosTools = require('appium-ci').iosTools,
    spawn = require('child_process').spawn,
    exec = Q.denodeify(require('child_process').exec),
    path = require('path');

var DEFAULT_OPTS = {
  files: ["*.js", "lib/**/*.js", "test/**/*.js", "!gulpfile.js"],
  transpile: true,
  transpileOut: "build",
  babelOpts: {},
  linkBabelRuntime: true,
  jscs: false,
  jshint: true,
  watch: true,
  watchE2E: false,
  test: {
    files: ['${testDir}/**/*-specs.js', '!${testDir}/**/*-e2e-specs.js']
  },
  coverage: {
    files: ['./test/**/*-specs.js', '!./test/**/*-e2e-specs.js'],
    verbose: true
   },
  e2eTest: {
    files: '${testDir}/**/*-e2e-specs.js'
  },
  testReporter: ( process.env.TRAVIS || process.env.CI ) ? 'spec' : 'nyan',
  testTimeout: 8000,
  buildName: null,
};

var DEFAULT_ANDROID_E2ETEST_OPTS = {
  "android-emu": true,
  "android-avd": "NEXUS_S_18_ARM"
};

// string interpolation
var interpolate = function (s, opts) {
  return _.keys(opts).reduce(function (s, k) {
    return s.replace(new RegExp('\\$\\{\\s*' + k + '\\s*\\}', 'g') , opts[k]);
  } , s);
};

var boilerplate = function (gulp, opts) {
  var spawnWatcher = require('../index').spawnWatcher.use(gulp);
  var runSequence = Q.denodeify(require('run-sequence').use(gulp));
  opts = _.cloneDeep(opts);
  _.defaults(opts, DEFAULT_OPTS);

  // re-defaulting when e2eTest.android=true
  if(opts.e2eTest.android) {
    _.defaults(opts.e2eTest, DEFAULT_OPTS.e2eTest);
    _.defaults(opts.e2eTest, DEFAULT_ANDROID_E2ETEST_OPTS);
  }
  // re-defaulting when e2eTest.ios=true
  if(opts.e2eTest.ios) {
    _.defaults(opts.e2eTest, DEFAULT_OPTS.e2eTest);
  }

  process.env.APPIUM_NOTIF_BUILD_NAME = opts.buildName;

  gulp.task('clean', function () {
    if (opts.transpile) {
      return gulp.src(opts.transpileOut, {read: false})
                 .pipe(vinylPaths(del));
    }
  });

  var testDeps = [];
  var testTasks = [];
  var rootDir = '.';
  if (opts.transpile) {
    testDeps.push('transpile');
    rootDir = opts.transpileOut;
  }
  var fileAliases = {rootDir: rootDir, testDir: rootDir + '/test', libDir: rootDir + '/lib' };

  if (opts.test) {
    var testFiles = _.flatten([opts.test.files || opts.testFiles]).map(function (f) {
      return interpolate(f, fileAliases);
    });
    gulp.task('unit-test', testDeps,  function () {
      var isForceLogMode = parseInt(process.env._FORCE_LOGS, 10) === 1;
      var mochaOpts = {
        reporter: isForceLogMode ? 'spec' : opts.testReporter,
        timeout: opts.testTimeout
      };
      // set env so our code knows when it's being run in a test env
      process.env._TESTING = 1;
      return gulp
       .src(testFiles, {read: false})
       .pipe(mocha(mochaOpts))
       .on('error', spawnWatcher.handleError);
    });
    testTasks.push('unit-test');
  }

  if (opts.coverage) {
    var covTestFiles = _.flatten([opts.coverage.files]).map(function (f) {
      return interpolate(f, fileAliases);
    });
    gulp.task('coverage', function () {
      return exec('rm -rf ./build').then(function () {
        return globby(covTestFiles).then(function (files) {
          var deferred = Q.defer();
          var bins = {};
          _.each(['isparta', '--report', 'text', '_mocha'], function (k) { bins[k] = path.resolve(__dirname, '../node_modules/.bin', k); });
          var bin = bins.isparta;
          var args = ['cover', bins._mocha, '--', '--require', __dirname + '/../babelhook', '--compilers', 'babel:babel/register' , '--reporter', 'dot']
            .concat(files);
          var env = _.clone(process.env);
          env.NO_PRECOMPILE=1;
          env._TESTING=1;
          console.log("running command -->", bin, args.join(' '));
          var proc = spawn(bin, args, {stdio: opts.coverage.verbose ? 'inherit' : 'ignore', env: env});
          proc.on('close', function (code) {
            if (code === 0) {
              deferred.resolve();
            } else {
              deferred.reject(new Error('Coverage command exit code: ' + code));
            }
          });
          return deferred.promise;
        });
      }).catch(spawnWatcher.handleError);
    });
    gulp.task('coveralls', ['coverage'], function () {
      var bin = path.resolve(__dirname, '../node_modules/.bin/coveralls');
      return exec('cat ./coverage/lcov.info | ' + bin).catch(spawnWatcher.handleError);
    });
  }

  if (opts.e2eTest) {
    var e2eTestFiles = _.flatten([opts.e2eTest.files || opts.e2eTestFiles]).map(function (f) {
      return interpolate(f, fileAliases);
    });
    gulp.task('e2e-test', testDeps,  function () {
      var isForceLogMode = parseInt(process.env._FORCE_LOGS, 10) === 1;
      var mochaOpts = {
        reporter: isForceLogMode ? 'spec' : opts.testReporter,
        timeout: opts.testTimeout
      };
      // set env so our code knows when it's being run in a test env
      process.env._TESTING = 1;
      var seq = [
        function () {
          return promisePipe(gulp
           .src(e2eTestFiles, {read: false})
           .pipe(mocha(mochaOpts))
           .on('error', spawnWatcher.handleError));
        }];
      if (opts.e2eTest.android) {
        if(opts.e2eTest.android["android-emu"]) {
          var emu = new AndroidEmulator(opts.e2eTest['android-avd']);
          seq = [
            function () { return androidTools.killAll(); },
            function () { return new Q(emu.start()); },
            function () { return emu.waitTillReady();}
          ].concat(seq).concat([
            function () { return emu.stop(); },
            function () { return androidTools.killAll(); }
          ]);
        } else {
          seq = [
            function () { return androidTools.killAll(); },
          ].concat(seq).concat([
            function () { return androidTools.killAll(); }
          ]);
        }
      }
      if (opts.e2eTest.ios) {
        var xCodeVersion = opts.e2eTest.xCodeVersion || '6.1.1';
        seq = [
          function () { return iosTools.killAll(); },
          function () { return iosTools.configureXcode(xCodeVersion); },
          function () { return iosTools.resetSims(); },
        ].concat(seq).concat([
          function () { return iosTools.killAll(); }
        ]);
      }
      return seq.reduce(Q.when, new Q()).catch(spawnWatcher.handleError);
    });
    testTasks.push('e2e-test');
  }

  if (testTasks.length > 0) {
    gulp.task('test', function () {
      return runSequence.apply(null, testTasks);
    });
  }

  if (opts.transpile) {
    gulp.task('transpile', function () {
      var transpiler = new Transpiler(opts.babelOpts);
      return gulp.src(opts.files, {base: './'})
        .pipe(transpiler.stream())
        .on('error', spawnWatcher.handleError)
        .pipe(gulp.dest(opts.transpileOut));
    });

    gulp.task('prepublish', function () {
      return runSequence('clean', 'transpile');
    });
  }

  var lintTasks = [];
  if (opts.jscs) {
    gulp.task('jscs', function () {
      return gulp
       .src(opts.files)
       .pipe(jscs())
       .on('error', spawnWatcher.handleError);
    });
    lintTasks.push('jscs');
  }

  if (opts.jshint) {
    gulp.task('jshint', function () {
      return gulp
       .src(opts.files)
       .pipe(jshint())
       .pipe(jshint.reporter('jshint-stylish'))
       .pipe(jshint.reporter('fail'))
       .on('error', spawnWatcher.handleError);
    });
    lintTasks.push('jshint');
  }

  if (opts.jscs || opts.jshint) {
    opts.lint = true;
    gulp.task('lint', lintTasks);
  }

  var defaultSequence = [];
  if (opts.transpile) defaultSequence.push('clean');
  if (opts.lint) defaultSequence.push('lint');
  if (opts.transpile && !opts.test) defaultSequence.push('transpile');
  if (opts.test) {
    if (opts.watchE2E) {
      defaultSequence.push('test');
    } else if (_.contains(testTasks, 'unit-test')) {
      defaultSequence.push('unit-test');
    }
  }
  if (opts.extraDefaultTasks) defaultSequence = defaultSequence.concat(opts.extraDefaultTasks);

  if (opts.watch) {
    spawnWatcher.clear(false);
    spawnWatcher.configure('watch', opts.files, function () {
      return runSequence.apply(null, defaultSequence);
    });
  }

  gulp.task('once', function () {
    return runSequence.apply(null, defaultSequence);
  });

  gulp.task('default', [opts.watch ? 'watch' : 'once']);
};

module.exports = {
  DEFAULTS: _.cloneDeep(DEFAULT_OPTS),
  use: function (gulp) {
    return function (opts) {
      boilerplate(gulp, opts);
    };
  }
};
<commit_msg>android e2e fix<commit_after>"use strict";
var mocha = require('gulp-mocha'),
    Q = require('q'),
    globby = Q.denodeify(require('globby')),
    Transpiler = require('../index').Transpiler,
    jshint = require('gulp-jshint'),
    jscs = require('gulp-jscs'),
    vinylPaths = require('vinyl-paths'),
    del = require('del'),
    _ = require('lodash'),
    promisePipe = require("promisepipe"),
    AndroidEmulator = require('appium-ci').AndroidEmulator,
    androidTools = require('appium-ci').androidTools,
    iosTools = require('appium-ci').iosTools,
    spawn = require('child_process').spawn,
    exec = Q.denodeify(require('child_process').exec),
    path = require('path');

var DEFAULT_OPTS = {
  files: ["*.js", "lib/**/*.js", "test/**/*.js", "!gulpfile.js"],
  transpile: true,
  transpileOut: "build",
  babelOpts: {},
  linkBabelRuntime: true,
  jscs: false,
  jshint: true,
  watch: true,
  watchE2E: false,
  test: {
    files: ['${testDir}/**/*-specs.js', '!${testDir}/**/*-e2e-specs.js']
  },
  coverage: {
    files: ['./test/**/*-specs.js', '!./test/**/*-e2e-specs.js'],
    verbose: true
   },
  e2eTest: {
    files: '${testDir}/**/*-e2e-specs.js'
  },
  testReporter: ( process.env.TRAVIS || process.env.CI ) ? 'spec' : 'nyan',
  testTimeout: 8000,
  buildName: null,
};

var DEFAULT_ANDROID_E2ETEST_OPTS = {
  "android-emu": true,
  "android-avd": "NEXUS_S_18_ARM"
};

// string interpolation
var interpolate = function (s, opts) {
  return _.keys(opts).reduce(function (s, k) {
    return s.replace(new RegExp('\\$\\{\\s*' + k + '\\s*\\}', 'g') , opts[k]);
  } , s);
};

var boilerplate = function (gulp, opts) {
  var spawnWatcher = require('../index').spawnWatcher.use(gulp);
  var runSequence = Q.denodeify(require('run-sequence').use(gulp));
  opts = _.cloneDeep(opts);
  _.defaults(opts, DEFAULT_OPTS);

  // re-defaulting when e2eTest.android=true
  if(opts.e2eTest.android) {
    _.defaults(opts.e2eTest, DEFAULT_OPTS.e2eTest);
    _.defaults(opts.e2eTest, DEFAULT_ANDROID_E2ETEST_OPTS);
  }
  // re-defaulting when e2eTest.ios=true
  if(opts.e2eTest.ios) {
    _.defaults(opts.e2eTest, DEFAULT_OPTS.e2eTest);
  }
  process.env.APPIUM_NOTIF_BUILD_NAME = opts.buildName;

  gulp.task('clean', function () {
    if (opts.transpile) {
      return gulp.src(opts.transpileOut, {read: false})
                 .pipe(vinylPaths(del));
    }
  });

  var testDeps = [];
  var testTasks = [];
  var rootDir = '.';
  if (opts.transpile) {
    testDeps.push('transpile');
    rootDir = opts.transpileOut;
  }
  var fileAliases = {rootDir: rootDir, testDir: rootDir + '/test', libDir: rootDir + '/lib' };

  if (opts.test) {
    var testFiles = _.flatten([opts.test.files || opts.testFiles]).map(function (f) {
      return interpolate(f, fileAliases);
    });
    gulp.task('unit-test', testDeps,  function () {
      var isForceLogMode = parseInt(process.env._FORCE_LOGS, 10) === 1;
      var mochaOpts = {
        reporter: isForceLogMode ? 'spec' : opts.testReporter,
        timeout: opts.testTimeout
      };
      // set env so our code knows when it's being run in a test env
      process.env._TESTING = 1;
      return gulp
       .src(testFiles, {read: false})
       .pipe(mocha(mochaOpts))
       .on('error', spawnWatcher.handleError);
    });
    testTasks.push('unit-test');
  }

  if (opts.coverage) {
    var covTestFiles = _.flatten([opts.coverage.files]).map(function (f) {
      return interpolate(f, fileAliases);
    });
    gulp.task('coverage', function () {
      return exec('rm -rf ./build').then(function () {
        return globby(covTestFiles).then(function (files) {
          var deferred = Q.defer();
          var bins = {};
          _.each(['isparta', '--report', 'text', '_mocha'], function (k) { bins[k] = path.resolve(__dirname, '../node_modules/.bin', k); });
          var bin = bins.isparta;
          var args = ['cover', bins._mocha, '--', '--require', __dirname + '/../babelhook', '--compilers', 'babel:babel/register' , '--reporter', 'dot']
            .concat(files);
          var env = _.clone(process.env);
          env.NO_PRECOMPILE=1;
          env._TESTING=1;
          console.log("running command -->", bin, args.join(' '));
          var proc = spawn(bin, args, {stdio: opts.coverage.verbose ? 'inherit' : 'ignore', env: env});
          proc.on('close', function (code) {
            if (code === 0) {
              deferred.resolve();
            } else {
              deferred.reject(new Error('Coverage command exit code: ' + code));
            }
          });
          return deferred.promise;
        });
      }).catch(spawnWatcher.handleError);
    });
    gulp.task('coveralls', ['coverage'], function () {
      var bin = path.resolve(__dirname, '../node_modules/.bin/coveralls');
      return exec('cat ./coverage/lcov.info | ' + bin).catch(spawnWatcher.handleError);
    });
  }

  if (opts.e2eTest) {
    var e2eTestFiles = _.flatten([opts.e2eTest.files || opts.e2eTestFiles]).map(function (f) {
      return interpolate(f, fileAliases);
    });
    gulp.task('e2e-test', testDeps,  function () {
      var isForceLogMode = parseInt(process.env._FORCE_LOGS, 10) === 1;
      var mochaOpts = {
        reporter: isForceLogMode ? 'spec' : opts.testReporter,
        timeout: opts.testTimeout
      };
      // set env so our code knows when it's being run in a test env
      process.env._TESTING = 1;
      var seq = [
        function () {
          return promisePipe(gulp
           .src(e2eTestFiles, {read: false})
           .pipe(mocha(mochaOpts))
           .on('error', spawnWatcher.handleError));
        }];
      if (opts.e2eTest.android) {
        if(opts.e2eTest["android-emu"]) {
          var emu = new AndroidEmulator(opts.e2eTest['android-avd']);
          seq = [
            function () { return androidTools.killAll(); },
            function () { return new Q(emu.start()); },
            function () { return emu.waitTillReady();}
          ].concat(seq).concat([
            function () { return emu.stop(); },
            function () { return androidTools.killAll(); }
          ]);
        } else {
          seq = [
            function () { return androidTools.killAll(); },
          ].concat(seq).concat([
            function () { return androidTools.killAll(); }
          ]);
        }
      }
      if (opts.e2eTest.ios) {
        var xCodeVersion = opts.e2eTest.xCodeVersion || '6.1.1';
        seq = [
          function () { return iosTools.killAll(); },
          function () { return iosTools.configureXcode(xCodeVersion); },
          function () { return iosTools.resetSims(); },
        ].concat(seq).concat([
          function () { return iosTools.killAll(); }
        ]);
      }
      return seq.reduce(Q.when, new Q()).catch(spawnWatcher.handleError);
    });
    testTasks.push('e2e-test');
  }

  if (testTasks.length > 0) {
    gulp.task('test', function () {
      return runSequence.apply(null, testTasks);
    });
  }

  if (opts.transpile) {
    gulp.task('transpile', function () {
      var transpiler = new Transpiler(opts.babelOpts);
      return gulp.src(opts.files, {base: './'})
        .pipe(transpiler.stream())
        .on('error', spawnWatcher.handleError)
        .pipe(gulp.dest(opts.transpileOut));
    });

    gulp.task('prepublish', function () {
      return runSequence('clean', 'transpile');
    });
  }

  var lintTasks = [];
  if (opts.jscs) {
    gulp.task('jscs', function () {
      return gulp
       .src(opts.files)
       .pipe(jscs())
       .on('error', spawnWatcher.handleError);
    });
    lintTasks.push('jscs');
  }

  if (opts.jshint) {
    gulp.task('jshint', function () {
      return gulp
       .src(opts.files)
       .pipe(jshint())
       .pipe(jshint.reporter('jshint-stylish'))
       .pipe(jshint.reporter('fail'))
       .on('error', spawnWatcher.handleError);
    });
    lintTasks.push('jshint');
  }

  if (opts.jscs || opts.jshint) {
    opts.lint = true;
    gulp.task('lint', lintTasks);
  }

  var defaultSequence = [];
  if (opts.transpile) defaultSequence.push('clean');
  if (opts.lint) defaultSequence.push('lint');
  if (opts.transpile && !opts.test) defaultSequence.push('transpile');
  if (opts.test) {
    if (opts.watchE2E) {
      defaultSequence.push('test');
    } else if (_.contains(testTasks, 'unit-test')) {
      defaultSequence.push('unit-test');
    }
  }
  if (opts.extraDefaultTasks) defaultSequence = defaultSequence.concat(opts.extraDefaultTasks);

  if (opts.watch) {
    spawnWatcher.clear(false);
    spawnWatcher.configure('watch', opts.files, function () {
      return runSequence.apply(null, defaultSequence);
    });
  }

  gulp.task('once', function () {
    return runSequence.apply(null, defaultSequence);
  });

  gulp.task('default', [opts.watch ? 'watch' : 'once']);
};

module.exports = {
  DEFAULTS: _.cloneDeep(DEFAULT_OPTS),
  use: function (gulp) {
    return function (opts) {
      boilerplate(gulp, opts);
    };
  }
};
<|endoftext|>


<commit_before>'use strict';

angular.module('admin').controller('LoginController', ['$scope', 'AuthService', '$location',
    function($scope, AuthService, $location) {

        $scope.login = function(credentials)
        {
            console.log(credentials);
            //$scope.invalid = !(AuthService.login($scope.credentials));
            AuthService.login(credentials).then(
                function (user)
                {
                    console.log(user.email);
                    $location.path('/admin/index');
                },
                function()
                {
                    $scope.invalid = true;
                });

        };

//        $scope.authentication = Authentication;
//
//        // If user is signed in then redirect back home
//        if ($scope.authentication.user) $location.path('/');
//
//        $scope.signup = function() {
//            $http.post('/auth/signup', $scope.credentials).success(function(response) {
//                // If successful we assign the response to the global user model
//                $scope.authentication.user = response;
//
//                // And redirect to the index page
//                $location.path('/');
//            }).error(function(response) {
//                $scope.error = response.message;
//            });
//        };
//
//        $scope.signin = function() {
//            $http.post('/auth/signin', $scope.credentials).success(function(response) {
//                // If successful we assign the response to the global user model
//                $scope.authentication.user = response;
//
//                // And redirect to the index page
//                $location.path('/');
//            }).error(function(response) {
//                $scope.error = response.message;
//            });
//        };
    }
]);<commit_msg>clean up console.log statements<commit_after>'use strict';

angular.module('admin').controller('LoginController', ['$scope', 'AuthService', '$location',
    function($scope, AuthService, $location) {

        $scope.login = function(credentials)
        {
            AuthService.login(credentials).then(
                function (user)
                {
                    $location.path('/admin/index');
                },
                function()
                {
                    $scope.invalid = true;
                });

        };

//        $scope.authentication = Authentication;
//
//        // If user is signed in then redirect back home
//        if ($scope.authentication.user) $location.path('/');
//
//        $scope.signup = function() {
//            $http.post('/auth/signup', $scope.credentials).success(function(response) {
//                // If successful we assign the response to the global user model
//                $scope.authentication.user = response;
//
//                // And redirect to the index page
//                $location.path('/');
//            }).error(function(response) {
//                $scope.error = response.message;
//            });
//        };
//
//        $scope.signin = function() {
//            $http.post('/auth/signin', $scope.credentials).success(function(response) {
//                // If successful we assign the response to the global user model
//                $scope.authentication.user = response;
//
//                // And redirect to the index page
//                $location.path('/');
//            }).error(function(response) {
//                $scope.error = response.message;
//            });
//        };
    }
]);<|endoftext|>


<commit_before>/**
 * Created by tamas on 2/18/15.
 */
require('../_globals');
var applyCLI = require('../../src/bin/apply'),
    importCLI = require('../../src/bin/import'),
    exportCLI = require('../../src/bin/export'),
    FS=require('fs'),
    should = require('chai').should,
    getJsonProject = function(path){
        return JSON.parse(FS.readFileSync(path,'utf-8'));
    },
    checkPath = function(object,path,value){
        var i;
        path = path.split('/');
        path.shift();
        for(i=0;i<path.length-1;i++){
            object = object[path[i]] || {};
        }
        if(object && object[path[i]] !== undefined){
            return object[path[i]].should.be.eql(value);
        }
        return i.should.be.eql(-1);
    };

describe('apply CLI tests',function(){
    describe('basic',function(){
        var jsonBaseProject;
        before(function(){
            jsonBaseProject = getJsonProject('./test/bin/apply/base001.json');
        });
        beforeEach(function(done){
            importCLI.import('mongodb://127.0.0.1:27017/multi','applyCliTest',jsonBaseProject,'base',done);
        });
        it('project should remain the same after applying empty patch',function(done){
            applyCLI.applyPatch('mongodb://127.0.0.1:27017/multi','applyCliTest','base',{},false,function(err,commit){
                if(err){
                    return done(err);
                }
                exportCLI.export('mongodb://127.0.0.1:27017/multi','applyCliTest',commit,function(err,jsonResultProject){
                    if(err){
                        return done(err);
                    }
                    jsonResultProject.should.be.eql(jsonBaseProject);
                    done();
                });
            });
        });
        it('simple attribute change',function(done){
            applyCLI.applyPatch('mongodb://127.0.0.1:27017/multi','applyCliTest','base',{attr:{name:"otherROOT"}},false,function(err,commit){
                if(err){
                    return done(err);
                }
                exportCLI.export('mongodb://127.0.0.1:27017/multi','applyCliTest',commit,function(err,jsonResultProject){
                    if(err){
                        return done(err);
                    }
                    checkPath(jsonResultProject,'/nodes/03d36072-9e09-7866-cb4e-d0a36ff825f6/attributes/name','otherROOT');
                    done();
                });
            });
        });
        //TODO fix this issue now tests has been removed
        /*it('multiple attribute change',function(done){
            applyCLI.applyPatch('mongodb://127.0.0.1:27017/multi','applyCliTest','base',{attr:{name:'ROOTy'},1:{attr:{name:'FCOy'}}},false,function(err,commit){
                if(err){
                    return done(err);
                }
                exportCLI.export('mongodb://127.0.0.1:27017/multi','applyCliTest',commit,function(err,jsonResultProject){
                    if(err){
                        return done(err);
                    }
                    checkPath(jsonResultProject,'/nodes/03d36072-9e09-7866-cb4e-d0a36ff825f6/attributes/name','ROOTy');
                    checkPath(jsonResultProject,'/nodes/cd891e7b-e2ea-e929-f6cd-9faf4f1fc045/attributes/name','FCOy');
                    done();
                });
            });
        });*/
        /*it('simple registry change',function(done){
            applyCLI.applyPatch('mongodb://127.0.0.1:27017/multi','applyCliTest','base',{1:{reg:{position:{x:200,y:200}}}},false,function(err,commit){
                if(err){
                    return done(err);
                }
                exportCLI.export('mongodb://127.0.0.1:27017/multi','applyCliTest',commit,function(err,jsonResultProject){
                    if(err){
                        return done(err);
                    }
                    checkPath(jsonResultProject,'/nodes/cd891e7b-e2ea-e929-f6cd-9faf4f1fc045/registry/position',{x:200,y:200});
                    done();
                });
            });
        });*/
    });
});<commit_msg>#162 fixing should include<commit_after>/**
 * Created by tamas on 2/18/15.
 */
require('../_globals');
var applyCLI = require('../../src/bin/apply'),
    importCLI = require('../../src/bin/import'),
    exportCLI = require('../../src/bin/export'),
    FS=require('fs'),
    should = require('chai').should(),
    getJsonProject = function(path){
        return JSON.parse(FS.readFileSync(path,'utf-8'));
    },
    checkPath = function(object,path,value){
        var i;
        path = path.split('/');
        path.shift();
        for(i=0;i<path.length-1;i++){
            object = object[path[i]] || {};
        }
        if(object && object[path[i]] !== undefined){
            return object[path[i]].should.be.eql(value);
        }
        return i.should.be.eql(-1);
    };

describe('apply CLI tests',function(){
    describe('basic',function(){
        var jsonBaseProject;
        before(function(){
            jsonBaseProject = getJsonProject('./test/bin/apply/base001.json');
        });
        beforeEach(function(done){
            importCLI.import('mongodb://127.0.0.1:27017/multi','applyCliTest',jsonBaseProject,'base',done);
        });
        it('project should remain the same after applying empty patch',function(done){
            applyCLI.applyPatch('mongodb://127.0.0.1:27017/multi','applyCliTest','base',{},false,function(err,commit){
                if(err){
                    return done(err);
                }
                exportCLI.export('mongodb://127.0.0.1:27017/multi','applyCliTest',commit,function(err,jsonResultProject){
                    if(err){
                        return done(err);
                    }
                    jsonResultProject.should.be.eql(jsonBaseProject);
                    done();
                });
            });
        });
        it('simple attribute change',function(done){
            applyCLI.applyPatch('mongodb://127.0.0.1:27017/multi','applyCliTest','base',{attr:{name:"otherROOT"}},false,function(err,commit){
                if(err){
                    return done(err);
                }
                exportCLI.export('mongodb://127.0.0.1:27017/multi','applyCliTest',commit,function(err,jsonResultProject){
                    if(err){
                        return done(err);
                    }
                    checkPath(jsonResultProject,'/nodes/03d36072-9e09-7866-cb4e-d0a36ff825f6/attributes/name','otherROOT');
                    done();
                });
            });
        });
        //TODO fix this issue now tests has been removed
        it('multiple attribute change',function(done){
            applyCLI.applyPatch('mongodb://127.0.0.1:27017/multi','applyCliTest','base',{attr:{name:'ROOTy'},1:{attr:{name:'FCOy'}}},false,function(err,commit){
                if(err){
                    return done(err);
                }
                exportCLI.export('mongodb://127.0.0.1:27017/multi','applyCliTest',commit,function(err,jsonResultProject){
                    if(err){
                        return done(err);
                    }
                    checkPath(jsonResultProject,'/nodes/03d36072-9e09-7866-cb4e-d0a36ff825f6/attributes/name','ROOTy');
                    checkPath(jsonResultProject,'/nodes/cd891e7b-e2ea-e929-f6cd-9faf4f1fc045/attributes/name','FCOy');
                    done();
                });
            });
        });
        /*it('simple registry change',function(done){
            applyCLI.applyPatch('mongodb://127.0.0.1:27017/multi','applyCliTest','base',{1:{reg:{position:{x:200,y:200}}}},false,function(err,commit){
                if(err){
                    return done(err);
                }
                exportCLI.export('mongodb://127.0.0.1:27017/multi','applyCliTest',commit,function(err,jsonResultProject){
                    if(err){
                        return done(err);
                    }
                    checkPath(jsonResultProject,'/nodes/cd891e7b-e2ea-e929-f6cd-9faf4f1fc045/registry/position',{x:200,y:200});
                    done();
                });
            });
        });*/
    });
});<|endoftext|>


<commit_before>(function() {
  'use strict';
  angular.module('core')
  .directive('malSearchItem', malSearchItem);
  malSearchItem.$inject = ['$timeout'];

  function malSearchItem($timeout) {
      return {
          restrict: 'A',
          require: '^malSearch',
          scope: {
            item: '@malSearchItem'
          },
          link: function (scope, element, attrs) {

          }
      };
  }

})();
<commit_msg>Update mal-search-item.directive.js<commit_after>(function() {
  'use strict';
  angular.module('core')
  .directive('malSearchItem', malSearchItem);
  malSearchItem.$inject = ['$timeout'];

  function malSearchItem($timeout) {
      return {
          restrict: 'A',
          require: '^malSearch',
          scope: {
            item: '@malSearchItem'
          },
          link: function (scope, element, attrs, malSearchCtrl) {

          }
      };
  }

})();
<|endoftext|>


<commit_before>'use strict';

// Create the 'chat' controller
angular.module('chat').controller('ChatController', ['$scope', '$resource', '$location', 'Authentication', 'Socket', 'Discussion', '$stateParams',
  function ($scope, $resource, $location, Authentication, Socket, Discussion, $stateParams) {
    // Create a messages array
    $scope.discussion = Discussion.get({discussionId: $stateParams.discussionId});
    $scope.messages = [];
    console.log($scope.discussion);
    console.log($scope.discussion.comments);

    $scope.rooms = [{
      messages: [],
      name: ''
    }];

    // If user is not signed in then redirect back home

    $scope.user = Authentication.user;

    if (!Authentication.user) {
      $location.path('/');
    }

    // Make sure the Socket is connected
    if (!Socket.socket) {
      Socket.connect();
    }

    console.log($stateParams.discussionId);
    var room = {
      roomID: $stateParams.discussionId
    };
    Socket.emit('createRoom', room);

    // Add an event listener to the 'chatMessage' event
    Socket.on('chatMessage', function (message) {
      //$scope.messages.unshift(message);
      $scope.messages.push(message);
    });

    // Create a controller method for sending messages
    $scope.sendMessage = function () {
      // Create a new message object
      var message = {
        text: this.messageText
      };

      // Emit a 'chatMessage' message event
      Socket.emit('chatMessage', message);

      // Clear the message text
      this.messageText = '';
    };

    // Remove the event listener when the controller instance is destroyed
    $scope.$on('$destroy', function () {
      Socket.removeListener('chatMessage');
    });
  }
<commit_msg>Minor tidying up in chat controller<commit_after>'use strict';

// Create the 'chat' controller
angular.module('chat').controller('ChatController', ['$scope', '$resource', '$location', 'Authentication', 'Socket', 'Discussion', '$stateParams',
  function ($scope, $resource, $location, Authentication, Socket, Discussion, $stateParams) {
    // Create a messages array
    $scope.discussion = Discussion.get({ discussionId: $stateParams.discussionId });
    $scope.messages = [];
    console.log($scope.discussion);
    console.log($scope.discussion.comments);

    $scope.rooms = [{
      messages: [],
      name: ''
    }];

    // If user is not signed in then redirect back home

    $scope.user = Authentication.user;

    if (!Authentication.user) {
      $location.path('/');
    }

    // Make sure the Socket is connected
    if (!Socket.socket) {
      Socket.connect();
    }

    console.log($stateParams.discussionId);
    var room = {
      roomID: $stateParams.discussionId
    };
    Socket.emit('createRoom', room);

    // Add an event listener to the 'chatMessage' event
    Socket.on('chatMessage', function (message) {
      //$scope.messages.unshift(message);
      $scope.messages.push(message);
    });

    // Create a controller method for sending messages
    $scope.sendMessage = function () {
      // Create a new message object
      var message = {
        text: this.messageText
      };

      // Emit a 'chatMessage' message event
      Socket.emit('chatMessage', message);

      // Clear the message text
      this.messageText = '';
    };

    // Remove the event listener when the controller instance is destroyed
    $scope.$on('$destroy', function () {
      Socket.removeListener('chatMessage');
    });
  }
]);<|endoftext|>


<commit_before>'use babel';

import fs from 'fs';
import path from 'path';
import util from 'util';
import EventEmitter from 'events';
import consistentEnv from 'consistent-env';

export function provideBuilder() {
  return class StackBuildProvider extends EventEmitter {
    constructor(cwd) {
      super();
      this.cwd = cwd;
    }

    getNiceName() {
      return 'stack';
    }

    isEligible() {
      this.file = [ 'stack.yaml', 'stack.yml' ]
        .map(file => path.join(this.cwd, file))
        .filter(fs.existsSync)
        .slice(0, 1)
        .pop();
      return !!this.file;
    }

    settings() {
      return
        [ { name: "All"
          , exec: "stack"
          , args: [ "build" ]
          , sh: false
          , env: consistentEnv()
          }
        ];
    }
  };
}
<commit_msg>Match errors.<commit_after>'use babel';

import fs from 'fs';
import path from 'path';
import util from 'util';
import EventEmitter from 'events';
import consistentEnv from 'consistent-env';

export function provideBuilder() {
  return class StackBuildProvider extends EventEmitter {
    constructor(cwd) {
      super();
      this.cwd = cwd;
    }

    getNiceName() {
      return 'stack';
    }

    isEligible() {
      this.file = [ 'stack.yaml', 'stack.yml' ]
        .map(file => path.join(this.cwd, file))
        .filter(fs.existsSync)
        .slice(0, 1)
        .pop();
      return !!this.file;
    }

    settings() {
      return
        [ { name: "All"
          , exec: "stack"
          , args: [ "build" ]
          , sh: false
          , env: consistentEnv()
          , errorMatch: [ /(?<file>.+\.l?hs):(?<line>\d+):(?<col>\d+):/ ]
          }
        ];
    }
  };
}
<|endoftext|>


<commit_before>(function() {

var module = angular.module('ui.grid');

function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}

/**
 *  @ngdoc service
 *  @name ui.grid.service:rowSearcher
 *
 *  @description Service for searching/filtering rows based on column value conditions.
 */
module.service('rowSearcher', ['gridUtil', 'uiGridConstants', function (gridUtil, uiGridConstants) {
  var defaultCondition = uiGridConstants.filter.STARTS_WITH;

  var rowSearcher = {};

  /**
   * @ngdoc function
   * @name getTerm
   * @methodOf ui.grid.service:rowSearcher
   * @description Get the term from a filter
   * Trims leading and trailing whitespace
   * @param {object} filter object to use
   * @returns {object} Parsed term
   */
  rowSearcher.getTerm = function getTerm(filter) {
    if (typeof(filter.term) === 'undefined') { return filter.term; }

    var term = filter.term;

    // Strip leading and trailing whitespace if the term is a string
    if (typeof(term) === 'string') {
      term = term.trim();
    }

    return term;
  };

  /**
   * @ngdoc function
   * @name stripTerm
   * @methodOf ui.grid.service:rowSearcher
   * @description Remove leading and trailing asterisk (*) from the filter's term
   * @param {object} filter object to use
   * @returns {uiGridConstants.filter<int>} Value representing the condition constant value
   */
  rowSearcher.stripTerm = function stripTerm(filter) {
    var term = rowSearcher.getTerm(filter);

    if (typeof(term) === 'string') {
      return escapeRegExp(term.replace(/(^\*|\*$)/g, ''));
    }
    else {
      return term;
    }
  };

  /**
   * @ngdoc function
   * @name guessCondition
   * @methodOf ui.grid.service:rowSearcher
   * @description Guess the condition for a filter based on its term
   *

   * Defaults to STARTS_WITH. Uses CONTAINS for strings beginning and ending with *s (*bob*).
   * Uses STARTS_WITH for strings ending with * (bo*). Uses ENDS_WITH for strings starting with * (*ob).
   * @param {object} filter object to use
   * @returns {uiGridConstants.filter<int>} Value representing the condition constant value
   */
  rowSearcher.guessCondition = function guessCondition(filter) {
    if (typeof(filter.term) === 'undefined' || !filter.term) {
      return defaultCondition;
    }

    var term = rowSearcher.getTerm(filter);

    if (/\*/.test(term)) {
      var regexpFlags = '';
      if (!filter.flags || !filter.flags.caseSensitive) {
        regexpFlags += 'i';
      }

      var reText = term.replace(/(\\)?\*/g, function ($0, $1) { return $1 ? $0 : '[\\s\\S]*?'; });
      return new RegExp('^' + reText + '$', regexpFlags);
    }
    // Otherwise default to default condition
    else {
      return defaultCondition;
    }
  };

  /**
   * @ngdoc function
   * @name setupFilters
   * @methodOf ui.grid.service:rowSearcher
   * @description For a given columns filters (either col.filters, or [col.filter] can be passed in),
   * do all the parsing and pre-processing and store that data into a new filters object.  The object
   * has the condition, the flags, the stripped term, and a parsed reg exp if there was one.
   *
   * We could use a forEach in here, since it's much less performance sensitive, but since we're using
   * for loops everywhere else in this module...
   *
   * @param {array} filters the filters from the column (col.filters or [col.filter])
   * @returns {array} An array of parsed/preprocessed filters
   */
  rowSearcher.setupFilters = function setupFilters( filters ){
    var newFilters = [];

    var filtersLength = filters.length;
    for ( var i = 0; i < filtersLength; i++ ){
      var filter = filters[i];

      if ( filter.noTerm || !gridUtil.isNullOrUndefined(filter.term) ){
        var newFilter = {};

        var regexpFlags = '';
        if (!filter.flags || !filter.flags.caseSensitive) {
          regexpFlags += 'i';
        }

        if ( !gridUtil.isNullOrUndefined(filter.term) ){
          // it is possible to have noTerm.  We don't need to copy that across, it was just a flag to avoid
          // getting the filter ignored if the filter was a function that didn't use a term
          newFilter.term = rowSearcher.stripTerm(filter);
        }

        if ( filter.condition ){
          newFilter.condition = filter.condition;
        } else {
          newFilter.condition = rowSearcher.guessCondition(filter);
        }

        newFilter.flags = angular.extend( { caseSensitive: false, date: false }, filter.flags );

        if (newFilter.condition === uiGridConstants.filter.STARTS_WITH) {
          newFilter.startswithRE = new RegExp('^' + newFilter.term, regexpFlags);
        }

         if (newFilter.condition === uiGridConstants.filter.ENDS_WITH) {
          newFilter.endswithRE = new RegExp(newFilter.term + '$', regexpFlags);
        }

        if (newFilter.condition === uiGridConstants.filter.CONTAINS) {
          newFilter.containsRE = new RegExp(newFilter.term, regexpFlags);
        }

        if (newFilter.condition === uiGridConstants.filter.EXACT) {
          newFilter.exactRE = new RegExp('^' + newFilter.term + '$', regexpFlags);
        }

        newFilters.push(newFilter);
      }
    }
    return newFilters;
  };

  /**
   * @ngdoc function
   * @name runColumnFilter
   * @methodOf ui.grid.service:rowSearcher
   * @description Runs a single pre-parsed filter against a cell, returning true
   * if the cell matches that one filter.
   *
   * @param {Grid} grid the grid we're working against
   * @param {GridRow} row the row we're matching against
   * @param {GridCol} column the column that we're working against
   * @param {object} filter the specific, preparsed, filter that we want to test
   * @returns {boolean} true if we match (row stays visible)
   */
  rowSearcher.runColumnFilter = function runColumnFilter(grid, row, column, filter) {
    // Cache typeof condition
    var conditionType = typeof(filter.condition);

    // Term to search for.
    var term = filter.term;

    // Get the column value for this row
    var value = grid.getCellValue(row, column);

    // If the filter's condition is a RegExp, then use it
    if (filter.condition instanceof RegExp) {
      return filter.condition.test(value);
    }

    // If the filter's condition is a function, run it
    if (conditionType === 'function') {
      return filter.condition(term, value, row, column);
    }

    if (filter.startswithRE) {
      return filter.startswithRE.test(value);
    }

    if (filter.endswithRE) {
      return filter.endswithRE.test(value);
    }

    if (filter.containsRE) {
      return filter.containsRE.test(value);
    }

    if (filter.exactRE) {
      return filter.exactRE.test(value);
    }

    if (filter.condition === uiGridConstants.filter.NOT_EQUAL) {
      var regex = new RegExp('^' + term + '$');
      return !regex.exec(value);
    }

    if (typeof(value) === 'number' && typeof(term) === 'string' ){
      // if the term has a decimal in it, it comes through as '9\.4', we need to take out the \
      // the same for negative numbers
      // TODO: I suspect the right answer is to look at escapeRegExp at the top of this code file, maybe it's not needed?
      var tempFloat = parseFloat(term.replace(/\\\./,'.').replace(/\\\-/,'-'));
      if (!isNaN(tempFloat)) {
        term = tempFloat;
      }
    }

    if (filter.flags.date === true) {
      value = new Date(value);
      // If the term has a dash in it, it comes through as '\-' -- we need to take out the '\'.
      term = new Date(term.replace(/\\/g, ''));
    }

    if (filter.condition === uiGridConstants.filter.GREATER_THAN) {
      return (value > term);
    }

    if (filter.condition === uiGridConstants.filter.GREATER_THAN_OR_EQUAL) {
      return (value >= term);
    }

    if (filter.condition === uiGridConstants.filter.LESS_THAN) {
      return (value < term);
    }

    if (filter.condition === uiGridConstants.filter.LESS_THAN_OR_EQUAL) {
      return (value <= term);
    }

    return true;
  };

  /**
   * @ngdoc boolean
   * @name useExternalFiltering
   * @propertyOf ui.grid.class:GridOptions
   * @description False by default. When enabled, this setting suppresses the internal filtering.
   * All UI logic will still operate, allowing filter conditions to be set and modified.
   *
   * The external filter logic can listen for the `filterChange` event, which fires whenever
   * a filter has been adjusted.
   */
  /**
   * @ngdoc function
   * @name searchColumn
   * @methodOf ui.grid.service:rowSearcher
   * @description Process provided filters on provided column against a given row. If the row meets
   * the conditions on all the filters, return true.
   * @param {Grid} grid Grid to search in
   * @param {GridRow} row Row to search on
   * @param {GridCol} column Column with the filters to use
   * @param {array} filters array of pre-parsed/preprocessed filters to apply
   * @returns {boolean} Whether the column matches or not.
   */
  rowSearcher.searchColumn = function searchColumn(grid, row, column, filters) {
    if (grid.options.useExternalFiltering) {
      return true;
    }

    var filtersLength = filters.length;
    for (var i = 0; i < filtersLength; i++) {
      var filter = filters[i];

      var ret = rowSearcher.runColumnFilter(grid, row, column, filter);
      if (!ret) {
        return false;
      }
    }

    return true;
  };

  /**
   * @ngdoc function
   * @name search
   * @methodOf ui.grid.service:rowSearcher
   * @description Run a search across the given rows and columns, marking any rows that don't
   * match the stored col.filters or col.filter as invisible.
   * @param {Grid} grid Grid instance to search inside
   * @param {Array[GridRow]} rows GridRows to filter
   * @param {Array[GridColumn]} columns GridColumns with filters to process
   */
  rowSearcher.search = function search(grid, rows, columns) {
    /*
     * Added performance optimisations into this code base, as this logic creates deeply nested
     * loops and is therefore very performance sensitive.  In particular, avoiding forEach as
     * this impacts some browser optimisers (particularly Chrome), using iterators instead
     */

    // Don't do anything if we weren't passed any rows
    if (!rows) {
      return;
    }

    // don't filter if filtering currently disabled
    if (!grid.options.enableFiltering){
      return rows;
    }

    // Build list of filters to apply
    var filterData = [];

    var colsLength = columns.length;
    for (var i = 0; i < colsLength; i++) {
      var col = columns[i];

      if (typeof(col.filters) !== 'undefined' && ( col.filters.length > 1 || col.filters.length === 1 && ( !gridUtil.isNullOrUndefined(col.filters[0].term) || col.filters[0].noTerm ) ) ) {
        filterData.push( { col: col, filters: rowSearcher.setupFilters(col.filters) } );
      }
      else if (typeof(col.filter) !== 'undefined' && col.filter && ( !gridUtil.isNullOrUndefined(col.filters[0].term) || col.filter.noTerm ) ) {
        filterData.push( { col: col, filters: rowSearcher.setupFilters([col.filter]) } );
      }
    }

    if (filterData.length > 0) {
      // define functions outside the loop, performance optimisation
      var foreachRow = function(grid, row, col, filters){
        if ( row.visible && !rowSearcher.searchColumn(grid, row, col, filters) ) {
          row.visible = false;
        }
      };

      var foreachFilterCol = function(grid, filterData){
        var rowsLength = rows.length;
        for ( var i = 0; i < rowsLength; i++){
          foreachRow(grid, rows[i], filterData.col, filterData.filters);
        }
      };

      // nested loop itself - foreachFilterCol, which in turn calls foreachRow
      var filterDataLength = filterData.length;
      for ( var j = 0; j < filterDataLength; j++){
        foreachFilterCol( grid, filterData[j] );
      }

      if (grid.api.core.raise.rowsVisibleChanged) {
        grid.api.core.raise.rowsVisibleChanged();
      }

      // drop any invisible rows
      // keeping these, as needed with filtering for trees - we have to come back and make parent nodes visible if child nodes are selected in the filter
      // rows = rows.filter(function(row){ return row.visible; });

    }

    return rows;
  };

  return rowSearcher;
}]);

})();
<commit_msg>Fix(filtering): fix #3678 empty string shouldn't filter<commit_after>(function() {

var module = angular.module('ui.grid');

function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}

/**
 *  @ngdoc service
 *  @name ui.grid.service:rowSearcher
 *
 *  @description Service for searching/filtering rows based on column value conditions.
 */
module.service('rowSearcher', ['gridUtil', 'uiGridConstants', function (gridUtil, uiGridConstants) {
  var defaultCondition = uiGridConstants.filter.STARTS_WITH;

  var rowSearcher = {};

  /**
   * @ngdoc function
   * @name getTerm
   * @methodOf ui.grid.service:rowSearcher
   * @description Get the term from a filter
   * Trims leading and trailing whitespace
   * @param {object} filter object to use
   * @returns {object} Parsed term
   */
  rowSearcher.getTerm = function getTerm(filter) {
    if (typeof(filter.term) === 'undefined') { return filter.term; }

    var term = filter.term;

    // Strip leading and trailing whitespace if the term is a string
    if (typeof(term) === 'string') {
      term = term.trim();
    }

    return term;
  };

  /**
   * @ngdoc function
   * @name stripTerm
   * @methodOf ui.grid.service:rowSearcher
   * @description Remove leading and trailing asterisk (*) from the filter's term
   * @param {object} filter object to use
   * @returns {uiGridConstants.filter<int>} Value representing the condition constant value
   */
  rowSearcher.stripTerm = function stripTerm(filter) {
    var term = rowSearcher.getTerm(filter);

    if (typeof(term) === 'string') {
      return escapeRegExp(term.replace(/(^\*|\*$)/g, ''));
    }
    else {
      return term;
    }
  };

  /**
   * @ngdoc function
   * @name guessCondition
   * @methodOf ui.grid.service:rowSearcher
   * @description Guess the condition for a filter based on its term
   *

   * Defaults to STARTS_WITH. Uses CONTAINS for strings beginning and ending with *s (*bob*).
   * Uses STARTS_WITH for strings ending with * (bo*). Uses ENDS_WITH for strings starting with * (*ob).
   * @param {object} filter object to use
   * @returns {uiGridConstants.filter<int>} Value representing the condition constant value
   */
  rowSearcher.guessCondition = function guessCondition(filter) {
    if (typeof(filter.term) === 'undefined' || !filter.term) {
      return defaultCondition;
    }

    var term = rowSearcher.getTerm(filter);

    if (/\*/.test(term)) {
      var regexpFlags = '';
      if (!filter.flags || !filter.flags.caseSensitive) {
        regexpFlags += 'i';
      }

      var reText = term.replace(/(\\)?\*/g, function ($0, $1) { return $1 ? $0 : '[\\s\\S]*?'; });
      return new RegExp('^' + reText + '$', regexpFlags);
    }
    // Otherwise default to default condition
    else {
      return defaultCondition;
    }
  };

  /**
   * @ngdoc function
   * @name setupFilters
   * @methodOf ui.grid.service:rowSearcher
   * @description For a given columns filters (either col.filters, or [col.filter] can be passed in),
   * do all the parsing and pre-processing and store that data into a new filters object.  The object
   * has the condition, the flags, the stripped term, and a parsed reg exp if there was one.
   *
   * We could use a forEach in here, since it's much less performance sensitive, but since we're using
   * for loops everywhere else in this module...
   *
   * @param {array} filters the filters from the column (col.filters or [col.filter])
   * @returns {array} An array of parsed/preprocessed filters
   */
  rowSearcher.setupFilters = function setupFilters( filters ){
    var newFilters = [];

    var filtersLength = filters.length;
    for ( var i = 0; i < filtersLength; i++ ){
      var filter = filters[i];

      if ( filter.noTerm || !gridUtil.isNullOrUndefined(filter.term) ){
        var newFilter = {};

        var regexpFlags = '';
        if (!filter.flags || !filter.flags.caseSensitive) {
          regexpFlags += 'i';
        }

        if ( !gridUtil.isNullOrUndefined(filter.term) ){
          // it is possible to have noTerm.  We don't need to copy that across, it was just a flag to avoid
          // getting the filter ignored if the filter was a function that didn't use a term
          newFilter.term = rowSearcher.stripTerm(filter);
        }

        if ( filter.condition ){
          newFilter.condition = filter.condition;
        } else {
          newFilter.condition = rowSearcher.guessCondition(filter);
        }

        newFilter.flags = angular.extend( { caseSensitive: false, date: false }, filter.flags );

        if (newFilter.condition === uiGridConstants.filter.STARTS_WITH) {
          newFilter.startswithRE = new RegExp('^' + newFilter.term, regexpFlags);
        }

         if (newFilter.condition === uiGridConstants.filter.ENDS_WITH) {
          newFilter.endswithRE = new RegExp(newFilter.term + '$', regexpFlags);
        }

        if (newFilter.condition === uiGridConstants.filter.CONTAINS) {
          newFilter.containsRE = new RegExp(newFilter.term, regexpFlags);
        }

        if (newFilter.condition === uiGridConstants.filter.EXACT) {
          newFilter.exactRE = new RegExp('^' + newFilter.term + '$', regexpFlags);
        }

        newFilters.push(newFilter);
      }
    }
    return newFilters;
  };

  /**
   * @ngdoc function
   * @name runColumnFilter
   * @methodOf ui.grid.service:rowSearcher
   * @description Runs a single pre-parsed filter against a cell, returning true
   * if the cell matches that one filter.
   *
   * @param {Grid} grid the grid we're working against
   * @param {GridRow} row the row we're matching against
   * @param {GridCol} column the column that we're working against
   * @param {object} filter the specific, preparsed, filter that we want to test
   * @returns {boolean} true if we match (row stays visible)
   */
  rowSearcher.runColumnFilter = function runColumnFilter(grid, row, column, filter) {
    // Cache typeof condition
    var conditionType = typeof(filter.condition);

    // Term to search for.
    var term = filter.term;

    // Get the column value for this row
    var value = grid.getCellValue(row, column);

    // If the filter's condition is a RegExp, then use it
    if (filter.condition instanceof RegExp) {
      return filter.condition.test(value);
    }

    // If the filter's condition is a function, run it
    if (conditionType === 'function') {
      return filter.condition(term, value, row, column);
    }

    if (filter.startswithRE) {
      return filter.startswithRE.test(value);
    }

    if (filter.endswithRE) {
      return filter.endswithRE.test(value);
    }

    if (filter.containsRE) {
      return filter.containsRE.test(value);
    }

    if (filter.exactRE) {
      return filter.exactRE.test(value);
    }

    if (filter.condition === uiGridConstants.filter.NOT_EQUAL) {
      var regex = new RegExp('^' + term + '$');
      return !regex.exec(value);
    }

    if (typeof(value) === 'number' && typeof(term) === 'string' ){
      // if the term has a decimal in it, it comes through as '9\.4', we need to take out the \
      // the same for negative numbers
      // TODO: I suspect the right answer is to look at escapeRegExp at the top of this code file, maybe it's not needed?
      var tempFloat = parseFloat(term.replace(/\\\./,'.').replace(/\\\-/,'-'));
      if (!isNaN(tempFloat)) {
        term = tempFloat;
      }
    }

    if (filter.flags.date === true) {
      value = new Date(value);
      // If the term has a dash in it, it comes through as '\-' -- we need to take out the '\'.
      term = new Date(term.replace(/\\/g, ''));
    }

    if (filter.condition === uiGridConstants.filter.GREATER_THAN) {
      return (value > term);
    }

    if (filter.condition === uiGridConstants.filter.GREATER_THAN_OR_EQUAL) {
      return (value >= term);
    }

    if (filter.condition === uiGridConstants.filter.LESS_THAN) {
      return (value < term);
    }

    if (filter.condition === uiGridConstants.filter.LESS_THAN_OR_EQUAL) {
      return (value <= term);
    }

    return true;
  };

  /**
   * @ngdoc boolean
   * @name useExternalFiltering
   * @propertyOf ui.grid.class:GridOptions
   * @description False by default. When enabled, this setting suppresses the internal filtering.
   * All UI logic will still operate, allowing filter conditions to be set and modified.
   *
   * The external filter logic can listen for the `filterChange` event, which fires whenever
   * a filter has been adjusted.
   */
  /**
   * @ngdoc function
   * @name searchColumn
   * @methodOf ui.grid.service:rowSearcher
   * @description Process provided filters on provided column against a given row. If the row meets
   * the conditions on all the filters, return true.
   * @param {Grid} grid Grid to search in
   * @param {GridRow} row Row to search on
   * @param {GridCol} column Column with the filters to use
   * @param {array} filters array of pre-parsed/preprocessed filters to apply
   * @returns {boolean} Whether the column matches or not.
   */
  rowSearcher.searchColumn = function searchColumn(grid, row, column, filters) {
    if (grid.options.useExternalFiltering) {
      return true;
    }

    var filtersLength = filters.length;
    for (var i = 0; i < filtersLength; i++) {
      var filter = filters[i];

      var ret = rowSearcher.runColumnFilter(grid, row, column, filter);
      if (!ret) {
        return false;
      }
    }

    return true;
  };

  /**
   * @ngdoc function
   * @name search
   * @methodOf ui.grid.service:rowSearcher
   * @description Run a search across the given rows and columns, marking any rows that don't
   * match the stored col.filters or col.filter as invisible.
   * @param {Grid} grid Grid instance to search inside
   * @param {Array[GridRow]} rows GridRows to filter
   * @param {Array[GridColumn]} columns GridColumns with filters to process
   */
  rowSearcher.search = function search(grid, rows, columns) {
    /*
     * Added performance optimisations into this code base, as this logic creates deeply nested
     * loops and is therefore very performance sensitive.  In particular, avoiding forEach as
     * this impacts some browser optimisers (particularly Chrome), using iterators instead
     */

    // Don't do anything if we weren't passed any rows
    if (!rows) {
      return;
    }

    // don't filter if filtering currently disabled
    if (!grid.options.enableFiltering){
      return rows;
    }

    // Build list of filters to apply
    var filterData = [];

    var colsLength = columns.length;

    var hasTerm = function( filters ) {
      var hasTerm = false;

      filters.forEach( function (filter) {
        if ( !gridUtil.isNullOrUndefined(filter.term) && filter.term !== '' || filter.noTerm ){
          hasTerm = true;
        }
      });

      return hasTerm;
    };

    for (var i = 0; i < colsLength; i++) {
      var col = columns[i];

      if (typeof(col.filters) !== 'undefined' && hasTerm(col.filters) ) {
        filterData.push( { col: col, filters: rowSearcher.setupFilters(col.filters) } );
      }
    }

    if (filterData.length > 0) {
      // define functions outside the loop, performance optimisation
      var foreachRow = function(grid, row, col, filters){
        if ( row.visible && !rowSearcher.searchColumn(grid, row, col, filters) ) {
          row.visible = false;
        }
      };

      var foreachFilterCol = function(grid, filterData){
        var rowsLength = rows.length;
        for ( var i = 0; i < rowsLength; i++){
          foreachRow(grid, rows[i], filterData.col, filterData.filters);
        }
      };

      // nested loop itself - foreachFilterCol, which in turn calls foreachRow
      var filterDataLength = filterData.length;
      for ( var j = 0; j < filterDataLength; j++){
        foreachFilterCol( grid, filterData[j] );
      }

      if (grid.api.core.raise.rowsVisibleChanged) {
        grid.api.core.raise.rowsVisibleChanged();
      }

      // drop any invisible rows
      // keeping these, as needed with filtering for trees - we have to come back and make parent nodes visible if child nodes are selected in the filter
      // rows = rows.filter(function(row){ return row.visible; });

    }

    return rows;
  };

  return rowSearcher;
}]);

})();
<|endoftext|>