<commit_before>/*
 * detect-dependencies.js
 * https://github.com/stephenplusplus/wiredep
 *
 * Copyright (c) 2013 Stephen Sawchuk
 * Licensed under the MIT license.
 */

'use strict';

var fs = require('fs');
var path = require('path');
var _ = require('lodash');
var helpers = require('./helpers');
var prop = helpers.prop;

/**
 * Find the component's JSON configuration file.
 *
 * @param  {object} config     the global configuration object
 * @param  {string} component  the name of the component to dig for
 * @return {object} the component's config file
 */
var findComponentConfigFile = function (config, component) {
  var componentConfigFile;

  ['.bower.json',
    'bower.json',
    'component.json',
    'package.json'].forEach(function (configFile) {
    configFile = path.join(config.get('directory'), component, configFile);

    if (!_.isObject(componentConfigFile) && fs.existsSync(configFile)) {
      componentConfigFile = JSON.parse(fs.readFileSync(configFile));
    }
  });

  return componentConfigFile;
};

/**
 * Find the main file the component refers to. It's not always main :(
 *
 * @param  {object} config        the global configuration object
 * @param  {string} component     the name of the component to dig for
 * @param  {componentConfigFile}  the component's config file
 * @return {array} the array of paths to the component's primary file(s)
 */
var findMainFiles = function (config, component, componentConfigFile) {
  var filePaths = [];
  var file;

  if (_.isString(componentConfigFile.main)) {
    // start by looking for what every component should have: config.main
    filePaths = [componentConfigFile.main];
  } else if (_.isArray(componentConfigFile.main)) {
    filePaths = componentConfigFile.main;
  } else if (_.isArray(componentConfigFile.scripts)) {
    // still haven't found it. is it stored in config.scripts, then?
    filePaths = componentConfigFile.scripts;
  } else {
    file = path.join(config.get('directory'), component, componentConfigFile.name + '.js');
    if (fs.existsSync(file)) {
      filePaths = [componentConfigFile.name + '.js'];
    }
  }

  return filePaths.map(function (file) {
    return path.join(config.get('directory'), component, file);
  });
};

/**
 * Store the information our prioritizer will need to determine rank.
 *
 * @param  {object} config   the global configuration object
 * @return {function} the iterator function, called on every component
 */
var gatherInfo = function (config) {
  /**
   * The iterator function, which is called on each component.
   *
   * @param  {string} version    the version of the component
   * @param  {string} component  the name of the component
   * @return {undefined}
   */
  return function (version, component) {
    var dep = config.get('global-dependencies').get(component) || {
      main: '',
      type: '',
      name: '',
      dependents: 0,
      dependencies: {}
    };

    var componentConfigFile = findComponentConfigFile(config, component);
    var warnings = config.get('warnings');

    var mains = findMainFiles(config, component, componentConfigFile);
    var fileTypes = _.chain(mains).map(function (main) {
      return path.extname(main);
    }).unique().value();

    dep.main = mains;
    dep.type = fileTypes;
    dep.name = componentConfigFile.name;
    dep.dependents += 1;

    if (dep.main.length === 0) {
      // can't find the main file. this config file is useless!
      warnings.push(component + ' was not injected in your file.');
      warnings.push(
        'Please go take a look in "'
        + path.join(config.get('directory'), component)
        + '" for the file you need, then manually include it in your file.');

      config.set('warnings', warnings);
      return;
    }

    if (componentConfigFile.dependencies) {
      dep.dependencies = componentConfigFile.dependencies;

      _.each(componentConfigFile.dependencies, gatherInfo(config));
    }

    config.get('global-dependencies').set(component, dep);
  };
};

/**
 * Compare two dependencies to determine priority.
 *
 * @param  {object} dependency      dependency a
 * @param  {object} lastDependency  dependency b
 * @return {number} the priority of dependency a in comparison to dependency b
 */
var dependencyComparator = function (dependency, lastDependency) {
  return Object.
    keys(dependency.dependencies).
    filter(function (dependency) {
      return dependency === lastDependency.name;
    }).length ? 1 : 0;
};

/**
 * Some dependencies which we know should always come first.
 */
var eliteDependencies = [
  'es5-shim',
  'jquery',
  'zepto',
  'modernizr'
];

/**
 * Sort the dependencies in the order we can best determine they're needed.
 *
 * @param  {object} config    the global configuration object
 * @param  {string} fileType  the type of file to prioritize
 * @return {array} the sorted items of 'path/to/main/files.ext' sorted by type
 */
var prioritizeDependencies = function (config, fileType) {
  var eliteDependenciesCaught = [];

  var dependencies =
    _.toArray(config.get('global-dependencies').get()).
      filter(function (dependency) {
        return _.contains(dependency.type, fileType);
      }).
      reduce(function (grouped, dependency) {
        return grouped.push(dependency) && grouped.sort(dependencyComparator);
      }, []).
      filter(function (dependency) {
        if (_.contains(eliteDependencies, dependency.name)) {
          eliteDependenciesCaught.push(dependency.main);
        } else {
          return true;
        }
      }).
      map(prop('main'));

  eliteDependenciesCaught.
    forEach(function (dependency) {
      dependencies.unshift(dependency);
    });

  return _
    (dependencies).
      flatten().
      value().
      filter(function (main) {
        return path.extname(main) === fileType;
      });
};

/**
 * Excludes dependencies that match any of the patterns.
 *
 * @param  {array} allDependencies  array of dependencies to filter
 * @param  {array} patterns         array of patterns to match against
 * @return {array} items that don't match any of the patterns
 */
var filterExcludedDependencies = function (allDependencies, patterns) {
  return _.transform(allDependencies, function (result, dependencies, fileType) {
    result[fileType] = _.reject(dependencies, function (dependency) {
      return _.find(patterns, function (pattern) {
        return dependency.match(pattern);
      });
    });
  });
};

/**
 * Detect dependencies of the components from `bower.json`.
 *
 * @param  {object} config the global configuration object.
 * @return {object} config
 */
module.exports = function detect(config) {
  _.each(config.get('bower.json').dependencies, gatherInfo(config));

  config.set('global-dependencies-sorted', filterExcludedDependencies({
    js: prioritizeDependencies(config, '.js'),
    css: prioritizeDependencies(config, '.css'),
    scss: prioritizeDependencies(config, '.scss')
  }, config.get('exclude')));

  return config;
};
<commit_msg>V8 + arrays with more than 10 elements = bomb. introducing merge sort.<commit_after>/*
 * detect-dependencies.js
 * https://github.com/stephenplusplus/wiredep
 *
 * Copyright (c) 2013 Stephen Sawchuk
 * Licensed under the MIT license.
 */

'use strict';

var fs = require('fs');
var path = require('path');
var _ = require('lodash');
var helpers = require('./helpers');
var prop = helpers.prop;

/**
 * Find the component's JSON configuration file.
 *
 * @param  {object} config     the global configuration object
 * @param  {string} component  the name of the component to dig for
 * @return {object} the component's config file
 */
var findComponentConfigFile = function (config, component) {
  var componentConfigFile;

  ['.bower.json',
    'bower.json',
    'component.json',
    'package.json'].forEach(function (configFile) {
    configFile = path.join(config.get('directory'), component, configFile);

    if (!_.isObject(componentConfigFile) && fs.existsSync(configFile)) {
      componentConfigFile = JSON.parse(fs.readFileSync(configFile));
    }
  });

  return componentConfigFile;
};

/**
 * Find the main file the component refers to. It's not always main :(
 *
 * @param  {object} config        the global configuration object
 * @param  {string} component     the name of the component to dig for
 * @param  {componentConfigFile}  the component's config file
 * @return {array} the array of paths to the component's primary file(s)
 */
var findMainFiles = function (config, component, componentConfigFile) {
  var filePaths = [];
  var file;

  if (_.isString(componentConfigFile.main)) {
    // start by looking for what every component should have: config.main
    filePaths = [componentConfigFile.main];
  } else if (_.isArray(componentConfigFile.main)) {
    filePaths = componentConfigFile.main;
  } else if (_.isArray(componentConfigFile.scripts)) {
    // still haven't found it. is it stored in config.scripts, then?
    filePaths = componentConfigFile.scripts;
  } else {
    file = path.join(config.get('directory'), component, componentConfigFile.name + '.js');
    if (fs.existsSync(file)) {
      filePaths = [componentConfigFile.name + '.js'];
    }
  }

  return filePaths.map(function (file) {
    return path.join(config.get('directory'), component, file);
  });
};

/**
 * Store the information our prioritizer will need to determine rank.
 *
 * @param  {object} config   the global configuration object
 * @return {function} the iterator function, called on every component
 */
var gatherInfo = function (config) {
  /**
   * The iterator function, which is called on each component.
   *
   * @param  {string} version    the version of the component
   * @param  {string} component  the name of the component
   * @return {undefined}
   */
  return function (version, component) {
    var dep = config.get('global-dependencies').get(component) || {
      main: '',
      type: '',
      name: '',
      dependencies: {}
    };

    var componentConfigFile = findComponentConfigFile(config, component);
    var warnings = config.get('warnings');

    var mains = findMainFiles(config, component, componentConfigFile);
    var fileTypes = _.chain(mains).map(function (main) {
      return path.extname(main);
    }).unique().value();

    dep.main = mains;
    dep.type = fileTypes;
    dep.name = componentConfigFile.name;

    if (dep.main.length === 0) {
      // can't find the main file. this config file is useless!
      warnings.push(component + ' was not injected in your file.');
      warnings.push(
        'Please go take a look in "'
        + path.join(config.get('directory'), component)
        + '" for the file you need, then manually include it in your file.');

      config.set('warnings', warnings);
      return;
    }

    if (componentConfigFile.dependencies) {
      dep.dependencies = componentConfigFile.dependencies;

      _.each(componentConfigFile.dependencies, gatherInfo(config));
    }

    config.get('global-dependencies').set(component, dep);
  };
};

/**
 * Compare two dependencies to determine priority.
 *
 * @param  {object} a  dependency a
 * @param  {object} b  dependency b
 * @return {number} the priority of dependency a in comparison to dependency b
 */
var dependencyComparator = function (a, b) {
  var aNeedsB = false;
  var bNeedsA = false;

  aNeedsB = Object.
    keys(a.dependencies).
    some(function (dependency) {
      return dependency === b.name;
    });

  if (aNeedsB) {
    return 1;
  }

  bNeedsA = Object.
    keys(b.dependencies).
    some(function (dependency) {
      return dependency === a.name;
    });

  if (bNeedsA) {
    return -1;
  }

  return 0;
};

/**
 * Take two arrays, sort based on their dependency relationship, then merge them
 * together.
 *
 * @param  {array} left
 * @param  {array} right
 * @return {array} the sorted, merged array
 */
var merge = function (left, right) {
  var result = [];
  var leftIndex = 0;
  var rightIndex = 0;

  while (leftIndex < left.length && rightIndex < right.length) {
    if (dependencyComparator(left[leftIndex], right[rightIndex]) < 1) {
      result.push(left[leftIndex++]);
    } else {
      result.push(right[rightIndex++]);
    }
  }

  return result.
    concat(left.slice(leftIndex)).
    concat(right.slice(rightIndex));
};

/**
 * Take an array and slice it in halves, sorting each half along the way.
 *
 * @param  {array} items
 * @return {array} the sorted array
 */
var mergeSort = function (items) {
  if (items.length < 2) {
    return items;
  }

  var middle = Math.floor(items.length / 2);

  return merge(
    mergeSort(items.slice(0, middle)),
    mergeSort(items.slice(middle))
  );
};

/**
 * Some dependencies which we know should always come first.
 */
var eliteDependencies = [
  'es5-shim',
  'jquery',
  'zepto',
  'modernizr'
];

/**
 * Sort the dependencies in the order we can best determine they're needed.
 *
 * @param  {object} config    the global configuration object
 * @param  {string} fileType  the type of file to prioritize
 * @return {array} the sorted items of 'path/to/main/files.ext' sorted by type
 */
var prioritizeDependencies = function (config, fileType) {
  var eliteDependenciesCaught = [];

  var dependencies = mergeSort(
    _.toArray(config.get('global-dependencies').get()).
      filter(function (dependency) {
        return _.contains(dependency.type, fileType);
      }).
      filter(function (dependency) {
        if (_.contains(eliteDependencies, dependency.name)) {
          eliteDependenciesCaught.push(dependency.main);
        } else {
          return true;
        }
      })
    ).map(prop('main'));

  eliteDependenciesCaught.
    forEach(function (dependency) {
      dependencies.unshift(dependency);
    });

  return _
    (dependencies).
      flatten().
      value().
      filter(function (main) {
        return path.extname(main) === fileType;
      });
};

/**
 * Excludes dependencies that match any of the patterns.
 *
 * @param  {array} allDependencies  array of dependencies to filter
 * @param  {array} patterns         array of patterns to match against
 * @return {array} items that don't match any of the patterns
 */
var filterExcludedDependencies = function (allDependencies, patterns) {
  return _.transform(allDependencies, function (result, dependencies, fileType) {
    result[fileType] = _.reject(dependencies, function (dependency) {
      return _.find(patterns, function (pattern) {
        return dependency.match(pattern);
      });
    });
  });
};

/**
 * Detect dependencies of the components from `bower.json`.
 *
 * @param  {object} config the global configuration object.
 * @return {object} config
 */
module.exports = function detect(config) {
  _.each(config.get('bower.json').dependencies, gatherInfo(config));

  config.set('global-dependencies-sorted', filterExcludedDependencies({
    js: prioritizeDependencies(config, '.js'),
    css: prioritizeDependencies(config, '.css'),
    scss: prioritizeDependencies(config, '.scss')
  }, config.get('exclude')));

  return config;
};
<|endoftext|>


<commit_before>/* @flow */
'use strict'

const path = require('path')

const { mkdir } = require('idempotent-fs')

const { filterByIsAccess } = require('../fs.js')
const { ensureArrayHead } = require('../data.js')
const { updateJson } = require('../json.js')
const { getPkg, isReactProject } = require('../pkg.js')
const { PACKAGE_JSON } = require('../values.js')

const LABEL = 'ESLint configured'

function eslintrc (cwd) {
  const rcPaths = [
    path.join(cwd, '.eslintrc'),
    path.join(cwd, '.eslintrc.json')
  ]
  const testRcPaths = [
    path.join(cwd, 'test', '.eslintrc'),
    path.join(cwd, 'test', '.eslintrc.json')
  ]
  let hasReact = false
  return getPkg(cwd)
    .then((pkg) => {
      hasReact = isReactProject(pkg)
    })
    .then(() => filterByIsAccess(rcPaths))
    .then(([ cfgPath = rcPaths[1] ]) => updateJson(cfgPath, (rc) => {
      rc.extends = rc.extends || []
      if (!Array.isArray(rc.extends)) {
        rc.extends = rc.extends || [ rc.extends ]
      }
      if (hasReact && !rc.extends.includes('standard-react')) {
        rc.extends = ensureArrayHead(rc.extends, 'standard-react')
      }
      if (!rc.extends.includes('semistandard')) {
        rc.extends = ensureArrayHead(rc.extends, 'standard')
      }
      rc.extends = ensureArrayHead(rc.extends, 'plugin:node/recommended')
      rc.extends = ensureArrayHead(rc.extends, 'eslint:recommended')

      rc.plugins = rc.plugins = []
      rc.plugins.push('node')

      return rc
    }))
    .then(() => mkdir(path.join(cwd, 'test')))
    .then(() => filterByIsAccess(testRcPaths))
    .then(([ cfgPath = testRcPaths[1] ]) => updateJson(cfgPath, (rc) => {
      rc.extends = rc.extends || []
      if (!Array.isArray(rc.extends)) {
        rc.extends = rc.extends || [ rc.extends ]
      }
      rc.extends = ensureArrayHead(rc.extends, path.join('..', path.basename(cfgPath)))

      rc.rules = rc.rules || {}
      // https://github.com/mysticatea/eslint-plugin-node/issues/47
      rc.rules['node/no-unpublished-require'] = 0

      return rc
    }))
}

/* :: import type { TaskOptions } from '../types.js' */

function fn ({ cwd } /* : TaskOptions */) {
  return eslintrc(cwd)
}

module.exports = {
  fn,
  id: path.basename(__filename),
  label: LABEL
}
<commit_msg>fix missing "requires" for eslintrc.json.js<commit_after>/* @flow */
'use strict'

const path = require('path')

const { mkdir } = require('idempotent-fs')

const { filterByIsAccess } = require('../fs.js')
const { ensureArrayHead } = require('../data.js')
const { updateJson } = require('../json.js')
const { getPkg, isReactProject } = require('../pkg.js')
const { PACKAGE_JSON } = require('../values.js')

const LABEL = 'ESLint configured'

function eslintrc (cwd) {
  const rcPaths = [
    path.join(cwd, '.eslintrc'),
    path.join(cwd, '.eslintrc.json')
  ]
  const testRcPaths = [
    path.join(cwd, 'test', '.eslintrc'),
    path.join(cwd, 'test', '.eslintrc.json')
  ]
  let hasReact = false
  return getPkg(cwd)
    .then((pkg) => {
      hasReact = isReactProject(pkg)
    })
    .then(() => filterByIsAccess(rcPaths))
    .then(([ cfgPath = rcPaths[1] ]) => updateJson(cfgPath, (rc) => {
      rc.extends = rc.extends || []
      if (!Array.isArray(rc.extends)) {
        rc.extends = rc.extends || [ rc.extends ]
      }
      if (hasReact && !rc.extends.includes('standard-react')) {
        rc.extends = ensureArrayHead(rc.extends, 'standard-react')
      }
      if (!rc.extends.includes('semistandard')) {
        rc.extends = ensureArrayHead(rc.extends, 'standard')
      }
      rc.extends = ensureArrayHead(rc.extends, 'plugin:node/recommended')
      rc.extends = ensureArrayHead(rc.extends, 'eslint:recommended')

      rc.plugins = rc.plugins = []
      rc.plugins.push('node')

      return rc
    }))
    .then(() => mkdir(path.join(cwd, 'test')))
    .then(() => filterByIsAccess(testRcPaths))
    .then(([ cfgPath = testRcPaths[1] ]) => updateJson(cfgPath, (rc) => {
      rc.extends = rc.extends || []
      if (!Array.isArray(rc.extends)) {
        rc.extends = rc.extends || [ rc.extends ]
      }
      rc.extends = ensureArrayHead(rc.extends, path.join('..', path.basename(cfgPath)))

      rc.rules = rc.rules || {}
      // https://github.com/mysticatea/eslint-plugin-node/issues/47
      rc.rules['node/no-unpublished-require'] = 0

      return rc
    }))
}

/* :: import type { TaskOptions } from '../types.js' */

function fn ({ cwd } /* : TaskOptions */) {
  return eslintrc(cwd)
}

module.exports = {
  fn,
  id: path.basename(__filename),
  label: LABEL,
  requires: [ PACKAGE_JSON ]
}
<|endoftext|>


<commit_before>'use strict';

var url = require('url');
var restifyClients = require('restify-clients');

var restify = require('../lib');

if (require.cache[__dirname + '/lib/helper.js']) {
    delete require.cache[__dirname + '/lib/helper.js'];
}
var helper = require('./lib/helper.js');

///--- Globals

var after = helper.after;
var before = helper.before;
var test = helper.test;

var PORT = process.env.UNIT_TEST_PORT || 0;
var CLIENT;
var SERVER;

var LOCALHOST;
var SLOCALHOST;

before(function (cb) {
    try {
        SERVER = restify.createServer({
            dtrace: helper.dtrace,
            log: helper.getLog('server'),
            version: ['2.0.0', '0.5.4', '1.4.3']
        });
        SERVER.use(restify.queryParser());
        SERVER.listen(PORT, '127.0.0.1', function () {
            PORT = SERVER.address().port;
            CLIENT = restifyClients.createJsonClient({
                url: 'http://127.0.0.1:' + PORT,
                dtrace: helper.dtrace,
                retry: false
            });
            LOCALHOST = 'http://' + '127.0.0.1:' + PORT;
            SLOCALHOST = 'https://' + '127.0.0.1:' + PORT;

            cb();
        });
    } catch (e) {
        console.error(e.stack);
        process.exit(1);
    }
});

after(function (cb) {
    try {
        CLIENT.close();
        SERVER.close(function () {
            CLIENT = null;
            SERVER = null;
            cb();
        });
    } catch (e) {
        console.error(e.stack);
        process.exit(1);
    }
});

// helper for joining array into strings
function join() {
    var args = [].slice.call(arguments, 0);
    return (args.join(''));
}

test('redirect to new string url as-is', function (t) {
    SERVER.get('/1', function (req, res, next) {
        res.redirect('www.foo.com', next);
    });

    CLIENT.get(join(LOCALHOST, '/1'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, 'www.foo.com');
        t.end();
    });
});

test('redirect to new relative string url as-is', function (t) {
    SERVER.get('/20', function (req, res, next) {
        res.redirect('/1', next);
    });

    CLIENT.get(join(LOCALHOST, '/20'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, '/1');
        t.end();
    });
});

test('redirect to current url (reload)', function (t) {
    SERVER.get('/2', function (req, res, next) {
        res.redirect({
            reload: true
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/2'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, join(LOCALHOST, '/2'));
        t.end();
    });
});

test('redirect to current url from http -> https', function (t) {
    SERVER.get('/3', function (req, res, next) {
        res.redirect({
            secure: true
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/3'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, join(SLOCALHOST, '/3'));
        t.end();
    });
});

test('redirect to current url from https -> http', function (t) {
    SERVER.get('/3', function (req, res, next) {
        res.redirect({
            reload: true,
            secure: false
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/3'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, join(LOCALHOST, '/3'));
        t.end();
    });
});

test('redirect by changing path', function (t) {
    SERVER.get('/4', function (req, res, next) {
        res.redirect({
            pathname: '1'
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/4'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, join(LOCALHOST, '/1'));
        t.end();
    });
});

test('redirect should add query params', function (t) {
    SERVER.get('/5', function (req, res, next) {
        res.redirect({
            query: {
                a: 1
            }
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/5'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, join(LOCALHOST, '/5?a=1'));
        t.end();
    });
});

test('redirect should extend existing query params', function (t) {
    SERVER.get('/6', function (req, res, next) {
        res.redirect({
            query: {
                b: 2
            }
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/6?a=1'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        var parsedUrl = url.parse(res.headers.location, true);
        t.deepEqual(parsedUrl.query, {
            a: 1,
            b: 2
        });
        t.equal(parsedUrl.query.b, 2);
        t.equal(parsedUrl.pathname, '/6');

        // t.equal(res.headers.location, join(LOCALHOST, '/6?a=1&b=2'));
        t.end();
    });
});

test('redirect should stomp over existing query params', function (t) {
    SERVER.get('/7', function (req, res, next) {
        res.redirect({
            overrideQuery: true,
            query: {
                b: 2
            }
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/7?a=1'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, join(LOCALHOST, '/7?b=2'));
        t.end();
    });
});

test('redirect with 301 status code', function (t) {
    SERVER.get('/8', function (req, res, next) {
        res.redirect({
            permanent: true
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/8'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 301);
        t.equal(res.headers.location, join(LOCALHOST, '/8'));
        t.end();
    });
});

test('redirect with 301 status code ising string url', function (t) {
    SERVER.get('/30', function (req, res, next) {
        res.redirect(301, '/foo', next);
    });

    CLIENT.get(join(LOCALHOST, '/30'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 301);
        t.equal(res.headers.location, '/foo');
        t.end();
    });
});

test('redirect using options.url', function (t) {
    SERVER.get('/8', function (req, res, next) {
        res.redirect({
            hostname: 'www.foo.com',
            pathname: '/8',
            query: {
                a: 1
            }
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/8'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, 'http://www.foo.com/8?a=1');
        t.end();
    });
});

// jscs:disable maximumLineLength
test('redirect should cause InternalError when invoked without next', function (t) {

    SERVER.get('/9', function (req, res, next) {
        res.redirect();
    });

    CLIENT.get(join(LOCALHOST, '/9'), function (err, _, res) {
        t.equal(res.statusCode, 500);

        // json parse the response
        var msg = JSON.parse(res.body);
        t.equal(msg.code, 'Internal');
        t.end();
    });
});

// jscs:enable maximumLineLength

test('redirect should call next with false to stop ' +
      'handler stack execution', function (t) {
    var wasRun = false;

    function A(req, res, next) {
        req.a = 1;
        next();
    }
    function B(req, res, next) {
        req.b = 2;
        wasRun = true;
        next();
    }
    function redirect(req, res, next) {
        res.redirect('/10', next);
    }

    SERVER.get('/10', [A, redirect, B]);

    CLIENT.get(join(LOCALHOST, '/10'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, '/10');

        // handler B should not be executed
        t.equal(wasRun, false);
        t.end();
    });
});

test('should fail to set header due to missing formatter', function (t) {

    // when a formatter is not set up for a specific content-type, restify will
    // default to octet-stream.

    SERVER.get('/11', function handle(req, res, next) {
        res.header('content-type', 'application/hal+json');
        res.send(200, JSON.stringify({ hello: 'world' }));
        return next();
    });

    CLIENT.get(join(LOCALHOST, '/11'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 200);
        t.equal(res.headers['content-type'], 'application/octet-stream');
        t.end();
    });
});
<commit_msg>Test sending of of null body<commit_after>'use strict';

var url = require('url');
var restifyClients = require('restify-clients');

var restify = require('../lib');

if (require.cache[__dirname + '/lib/helper.js']) {
    delete require.cache[__dirname + '/lib/helper.js'];
}
var helper = require('./lib/helper.js');

///--- Globals

var after = helper.after;
var before = helper.before;
var test = helper.test;

var PORT = process.env.UNIT_TEST_PORT || 0;
var CLIENT;
var SERVER;

var LOCALHOST;
var SLOCALHOST;

before(function (cb) {
    try {
        SERVER = restify.createServer({
            dtrace: helper.dtrace,
            log: helper.getLog('server'),
            version: ['2.0.0', '0.5.4', '1.4.3']
        });
        SERVER.use(restify.queryParser());
        SERVER.listen(PORT, '127.0.0.1', function () {
            PORT = SERVER.address().port;
            CLIENT = restifyClients.createJsonClient({
                url: 'http://127.0.0.1:' + PORT,
                dtrace: helper.dtrace,
                retry: false
            });
            LOCALHOST = 'http://' + '127.0.0.1:' + PORT;
            SLOCALHOST = 'https://' + '127.0.0.1:' + PORT;

            cb();
        });
    } catch (e) {
        console.error(e.stack);
        process.exit(1);
    }
});

after(function (cb) {
    try {
        CLIENT.close();
        SERVER.close(function () {
            CLIENT = null;
            SERVER = null;
            cb();
        });
    } catch (e) {
        console.error(e.stack);
        process.exit(1);
    }
});

// helper for joining array into strings
function join() {
    var args = [].slice.call(arguments, 0);
    return (args.join(''));
}

test('redirect to new string url as-is', function (t) {
    SERVER.get('/1', function (req, res, next) {
        res.redirect('www.foo.com', next);
    });

    CLIENT.get(join(LOCALHOST, '/1'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, 'www.foo.com');
        t.end();
    });
});

test('redirect to new relative string url as-is', function (t) {
    SERVER.get('/20', function (req, res, next) {
        res.redirect('/1', next);
    });

    CLIENT.get(join(LOCALHOST, '/20'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, '/1');
        t.end();
    });
});

test('redirect to current url (reload)', function (t) {
    SERVER.get('/2', function (req, res, next) {
        res.redirect({
            reload: true
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/2'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, join(LOCALHOST, '/2'));
        t.end();
    });
});

test('redirect to current url from http -> https', function (t) {
    SERVER.get('/3', function (req, res, next) {
        res.redirect({
            secure: true
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/3'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, join(SLOCALHOST, '/3'));
        t.end();
    });
});

test('redirect to current url from https -> http', function (t) {
    SERVER.get('/3', function (req, res, next) {
        res.redirect({
            reload: true,
            secure: false
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/3'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, join(LOCALHOST, '/3'));
        t.end();
    });
});

test('redirect by changing path', function (t) {
    SERVER.get('/4', function (req, res, next) {
        res.redirect({
            pathname: '1'
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/4'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, join(LOCALHOST, '/1'));
        t.end();
    });
});

test('redirect should add query params', function (t) {
    SERVER.get('/5', function (req, res, next) {
        res.redirect({
            query: {
                a: 1
            }
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/5'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, join(LOCALHOST, '/5?a=1'));
        t.end();
    });
});

test('redirect should extend existing query params', function (t) {
    SERVER.get('/6', function (req, res, next) {
        res.redirect({
            query: {
                b: 2
            }
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/6?a=1'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        var parsedUrl = url.parse(res.headers.location, true);
        t.deepEqual(parsedUrl.query, {
            a: 1,
            b: 2
        });
        t.equal(parsedUrl.query.b, 2);
        t.equal(parsedUrl.pathname, '/6');

        // t.equal(res.headers.location, join(LOCALHOST, '/6?a=1&b=2'));
        t.end();
    });
});

test('redirect should stomp over existing query params', function (t) {
    SERVER.get('/7', function (req, res, next) {
        res.redirect({
            overrideQuery: true,
            query: {
                b: 2
            }
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/7?a=1'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, join(LOCALHOST, '/7?b=2'));
        t.end();
    });
});

test('redirect with 301 status code', function (t) {
    SERVER.get('/8', function (req, res, next) {
        res.redirect({
            permanent: true
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/8'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 301);
        t.equal(res.headers.location, join(LOCALHOST, '/8'));
        t.end();
    });
});

test('redirect with 301 status code ising string url', function (t) {
    SERVER.get('/30', function (req, res, next) {
        res.redirect(301, '/foo', next);
    });

    CLIENT.get(join(LOCALHOST, '/30'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 301);
        t.equal(res.headers.location, '/foo');
        t.end();
    });
});

test('redirect using options.url', function (t) {
    SERVER.get('/8', function (req, res, next) {
        res.redirect({
            hostname: 'www.foo.com',
            pathname: '/8',
            query: {
                a: 1
            }
        }, next);
    });

    CLIENT.get(join(LOCALHOST, '/8'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, 'http://www.foo.com/8?a=1');
        t.end();
    });
});

// jscs:disable maximumLineLength
test('redirect should cause InternalError when invoked without next', function (t) {

    SERVER.get('/9', function (req, res, next) {
        res.redirect();
    });

    CLIENT.get(join(LOCALHOST, '/9'), function (err, _, res) {
        t.equal(res.statusCode, 500);

        // json parse the response
        var msg = JSON.parse(res.body);
        t.equal(msg.code, 'Internal');
        t.end();
    });
});

// jscs:enable maximumLineLength

test('redirect should call next with false to stop ' +
      'handler stack execution', function (t) {
    var wasRun = false;

    function A(req, res, next) {
        req.a = 1;
        next();
    }
    function B(req, res, next) {
        req.b = 2;
        wasRun = true;
        next();
    }
    function redirect(req, res, next) {
        res.redirect('/10', next);
    }

    SERVER.get('/10', [A, redirect, B]);

    CLIENT.get(join(LOCALHOST, '/10'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 302);
        t.equal(res.headers.location, '/10');

        // handler B should not be executed
        t.equal(wasRun, false);
        t.end();
    });
});

test('should fail to set header due to missing formatter', function (t) {

    // when a formatter is not set up for a specific content-type, restify will
    // default to octet-stream.

    SERVER.get('/11', function handle(req, res, next) {
        res.header('content-type', 'application/hal+json');
        res.send(200, JSON.stringify({ hello: 'world' }));
        return next();
    });

    CLIENT.get(join(LOCALHOST, '/11'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 200);
        t.equal(res.headers['content-type'], 'application/octet-stream');
        t.end();
    });
});

test('should not fail to send null as body', function (t) {

    SERVER.get('/12', function handle(req, res, next) {
        res.send(200, null);
        return next();
    });

    CLIENT.get(join(LOCALHOST, '/12'), function (err, _, res) {
        t.ifError(err);
        t.equal(res.statusCode, 200);
        t.end();
    });
});
<|endoftext|>


<commit_before>var DIC_URL = "bower_components/kuromoji/dist/dict/";

var tokenizer = null;

var vm = new Vue({
    el: "#demo",
    data: {
        inputText: "",
        tokens: [],
        isLoading: true,
        message: "Loading dictionaries ...",
        svgStyle: "hidden"
    },
    methods: {
        tokenize: function () {
            if (vm.inputText == "" || tokenizer == null) {
                vm.tokens = [];
                // lattice = null;
                return;
            }
            try {
                // lattice = tokenizer.getLattice(vm.inputText);
                vm.tokens = tokenizer.tokenize(vm.inputText);
            } catch (e) {
                console.log(e);
                // lattice = null;
                vm.tokens = [];
            }
        }
    }
});

// フォームの内容が変化したらtokenizeする
vm.$watch("inputText", function (value) {
    vm.svgStyle = "hidden";
    vm.tokenize();
});

// Load and prepare tokenizer
kuromoji.builder({ dicPath: DIC_URL }).build(function (error, _tokenizer) {
    if (error != null) {
        console.log(error);
    }
    tokenizer = _tokenizer;

    vm.message = "Ready";

    vm.inputText = "すもももももももものうち";
    vm.isLoading = false;
    document.getElementById('export_csv').className = "btn btn-default"
});

var button = document.getElementById('export_csv');
button.onclick = function() {
  var content = build_csv();
  var blob = new Blob([ content ], { type: "text/csv;charset=utf-16;" });
  this.href = window.URL.createObjectURL(blob);
  this.download = vm.tokens[0].surface_form + "_tokens.csv";
}

function build_csv() {
  var csv_string = "";

  var header = ['表層形','品詞','品詞細分類1','品詞細分類2','品詞細分類3','活用型','活用形','基本形','読み','発音']

  csv_string += header;
  csv_string += '\r\n';

  for(var i = 0; i < vm.tokens.length; i++) {
    var token = vm.tokens[i];
    csv_string += ([token.surface_form, token.pos, token.pos_detail_1, token.pos_detail_2, token.pos_detail_3, token.conjugated_type, token.conjugated_form, token.basic_form, token.reading, token.pronunciation])
    csv_string += '\r\n';
  }

  // BOM追加
  csv_string = "\ufffe" + csv_string;

  // if (isLittleEndian()) {

  //   //実行環境のエンディアンがLEならTypedArrayを利用
  //   var array = [];
  //   for (var i=0; i<csv_string.length; i++){
  //       array.push(csv_string.charCodeAt(i));
  //   }
  //   var csv_contents = new Uint16Array(array);

  // } else {

  //   //LEでない場合はDataViewでUTF-16LEのArrayBufferを作成
  //   var array_buffer = new ArrayBuffer(csv_string.length * 2);
  //   var data_view = new DataView(array_buffer);
  //   for (var i=0,j=0; i<csv_string.length; i++,j=i*2) {
  //       data_view.setUint16( j, csv_string.charCodeAt(i), true ); //第3引数にtrueを渡すとLEになる
  //   }
  //   var csv_contents = array_buffer
  // }

  return csv_string;
}

function isLittleEndian(){
    if ((new Uint8Array((new Uint16Array([0x00ff])).buffer))[0]) return true;
    return false;
}
<commit_msg>replace node_modules<commit_after>var DIC_URL = "node_modules/kuromoji/dist/dict/";

var tokenizer = null;

var vm = new Vue({
    el: "#demo",
    data: {
        inputText: "",
        tokens: [],
        isLoading: true,
        message: "Loading dictionaries ...",
        svgStyle: "hidden"
    },
    methods: {
        tokenize: function () {
            if (vm.inputText == "" || tokenizer == null) {
                vm.tokens = [];
                // lattice = null;
                return;
            }
            try {
                // lattice = tokenizer.getLattice(vm.inputText);
                vm.tokens = tokenizer.tokenize(vm.inputText);
            } catch (e) {
                console.log(e);
                // lattice = null;
                vm.tokens = [];
            }
        }
    }
});

// フォームの内容が変化したらtokenizeする
vm.$watch("inputText", function (value) {
    vm.svgStyle = "hidden";
    vm.tokenize();
});

// Load and prepare tokenizer
kuromoji.builder({ dicPath: DIC_URL }).build(function (error, _tokenizer) {
    if (error != null) {
        console.log(error);
    }
    tokenizer = _tokenizer;

    vm.message = "Ready";

    vm.inputText = "すもももももももものうち";
    vm.isLoading = false;
    document.getElementById('export_csv').className = "btn btn-default"
});

var button = document.getElementById('export_csv');
button.onclick = function() {
  var content = build_csv();
  var blob = new Blob([ content ], { type: "text/csv;charset=utf-16;" });
  this.href = window.URL.createObjectURL(blob);
  this.download = vm.tokens[0].surface_form + "_tokens.csv";
}

function build_csv() {
  var csv_string = "";

  var header = ['表層形','品詞','品詞細分類1','品詞細分類2','品詞細分類3','活用型','活用形','基本形','読み','発音']

  csv_string += header;
  csv_string += '\r\n';

  for(var i = 0; i < vm.tokens.length; i++) {
    var token = vm.tokens[i];
    csv_string += ([token.surface_form, token.pos, token.pos_detail_1, token.pos_detail_2, token.pos_detail_3, token.conjugated_type, token.conjugated_form, token.basic_form, token.reading, token.pronunciation])
    csv_string += '\r\n';
  }

  // BOM追加
  csv_string = "\ufffe" + csv_string;

  // if (isLittleEndian()) {

  //   //実行環境のエンディアンがLEならTypedArrayを利用
  //   var array = [];
  //   for (var i=0; i<csv_string.length; i++){
  //       array.push(csv_string.charCodeAt(i));
  //   }
  //   var csv_contents = new Uint16Array(array);

  // } else {

  //   //LEでない場合はDataViewでUTF-16LEのArrayBufferを作成
  //   var array_buffer = new ArrayBuffer(csv_string.length * 2);
  //   var data_view = new DataView(array_buffer);
  //   for (var i=0,j=0; i<csv_string.length; i++,j=i*2) {
  //       data_view.setUint16( j, csv_string.charCodeAt(i), true ); //第3引数にtrueを渡すとLEになる
  //   }
  //   var csv_contents = array_buffer
  // }

  return csv_string;
}

function isLittleEndian(){
    if ((new Uint8Array((new Uint16Array([0x00ff])).buffer))[0]) return true;
    return false;
}
<|endoftext|>


<commit_before>'use strict';

const child_process = require('child_process');
const spawn = child_process.spawn, execSync = child_process.execSync;
const fs = require('fs');
const http = require('http');
const path = require('path');
const chalk = require('chalk');
const glob = require('glob');
const parse = require('xml-parser');
const WinAppDeployTool = require('./winappdeploytool');

function getAppPackage(options) {
  return glob.sync(path.join(options.root, 'windows/*/AppPackages/*'))[0];
}

function getWindowsStoreAppUtils(options) {
  const appStorePath = path.join(options.root, 'node_modules/react-native-windows/local-cli/runWindows/utils/WindowsStoreAppUtils.ps1');
  execSync(`powershell Unblock-File "${appStorePath}"`);
  return appStorePath;
}

function getAppxManifest(options) {
  const appxPath = glob.sync(path.join(options.root, 'windows/*/bin/*/*/AppxManifest.xml'))[0];
  return parse(fs.readFileSync(appxPath, 'utf8'));
}

function handleResponseError(e) {
  if (e.message.indexOf('Error code -2146233088')) {
    throw new Error(`No Windows Mobile device was detected: ${e.message}`);
  } else {
    throw new Error(`Unexpected error deploying app: ${e.message}`);
  }
}

// Errors: 0x80073d10 - bad architecture
function deployToDevice(options) {
  const appPackageFolder = getAppPackage(options);

  const deployTarget = options.target ? options.target : (options.emulator ? 'emulator' : 'device');
  const deployTool = new WinAppDeployTool();
  const appxManifest = getAppxManifest(options);
  const identity = appxManifest.root.children.filter(function (x) { return x.name === 'mp:PhoneIdentity'; })[0];
  const appName = identity.attributes.PhoneProductId;

  return new Promise(resolve => {
    const device = deployTool.findDevice(deployTarget);

    try {
      deployTool.uninstallAppPackage(appName, device);
    } catch (e) {
      console.log(chalk.yellow('Failed to uninstall app from ' + device.name));
    }

    const appxFile = glob.sync(path.join(appPackageFolder, '*.appx'))[0];
    try {
      console.log(chalk.white(deployTool.installAppPackage(appxFile, device, true, false)));
      resolve();
    } catch (e) {
      if (e.message.indexOf('Error code 2148734208 for command') !== -1) {
        console.log(chalk.white(deployTool.installAppPackage(appxFile, device, true, true)));
        resolve();
      } else {
        handleResponseError(e);
      }
    }
  });
}

function deployToDesktop(options) {
  const appPackageFolder = getAppPackage(options);

  const windowsStoreAppUtils = getWindowsStoreAppUtils();
  const appxManifest = getAppxManifest(options);
  const identity = appxManifest.root.children.filter(function (x) { return x.name === 'Identity'; })[0];
  const appName = identity.attributes.Name;
  const script = glob.sync(path.join(appPackageFolder, 'Add-AppDevPackage.ps1'))[0];

  return new Promise(resolve => {
    console.log(chalk.green('Removing old version of the app'));
    execSync(`powershell -ExecutionPolicy RemoteSigned Import-Module "${windowsStoreAppUtils}" ; Uninstall-App ${appName}`);

    console.log(chalk.green('Installing new version of the app'));
    execSync(`powershell -ExecutionPolicy RemoteSigned Import-Module "${windowsStoreAppUtils}"; Install-App "${script}"`);

    console.log(chalk.green('Starting the app'));
    execSync(`powershell -ExecutionPolicy RemoteSigned Import-Module "${windowsStoreAppUtils}"; Start-Locally ${appName}`);
    resolve();
  });
}

function startServerInNewWindow(options) {
  return new Promise(resolve => {
    http.get('http://localhost:8081/status', res => {
      if (res === 200) {
        console.log(chalk.green('React-Native Server already started'));
        resolve();
      }
    }).on('error', () => resolve(launchServer(options)));
  });
}

function launchServer(options) {
  console.log(chalk.green('Starting the React-Native Server'));
  const launchPackagerScript = path.join('node_modules/react-native/packager/launchPackager.bat');
  const opts = {
    cwd: options.root,
    detached: true,
    stdio: 'ignore'
  };

  return Promise.resolve(spawn('cmd.exe', ['/C', 'start', launchPackagerScript], opts));
}

module.exports = {
  deployToDesktop,
  deployToDevice,
  startServerInNewWindow
};
<commit_msg>fix(runWindows): Fixes deployToDesktop method for runWindows CLI (#494)<commit_after>'use strict';

const child_process = require('child_process');
const spawn = child_process.spawn, execSync = child_process.execSync;
const fs = require('fs');
const http = require('http');
const path = require('path');
const chalk = require('chalk');
const glob = require('glob');
const parse = require('xml-parser');
const WinAppDeployTool = require('./winappdeploytool');

function getAppPackage(options) {
  return glob.sync(path.join(options.root, 'windows/*/AppPackages/*'))[0];
}

function getWindowsStoreAppUtils(options) {
  const appStorePath = path.join(options.root, 'node_modules/react-native-windows/local-cli/runWindows/utils/WindowsStoreAppUtils.ps1');
  execSync(`powershell Unblock-File "${appStorePath}"`);
  return appStorePath;
}

function getAppxManifest(options) {
  const configuration = options.debug ? 'Debug' : 'Release';
  const appxPath = glob.sync(path.join(options.root, `windows/*/bin/${options.arch}/${configuration}/AppxManifest.xml`))[0];
  return parse(fs.readFileSync(appxPath, 'utf8'));
}

function handleResponseError(e) {
  if (e.message.indexOf('Error code -2146233088')) {
    throw new Error(`No Windows Mobile device was detected: ${e.message}`);
  } else {
    throw new Error(`Unexpected error deploying app: ${e.message}`);
  }
}

// Errors: 0x80073d10 - bad architecture
function deployToDevice(options) {
  const appPackageFolder = getAppPackage(options);

  const deployTarget = options.target ? options.target : (options.emulator ? 'emulator' : 'device');
  const deployTool = new WinAppDeployTool();
  const appxManifest = getAppxManifest(options);
  const identity = appxManifest.root.children.filter(function (x) { return x.name === 'mp:PhoneIdentity'; })[0];
  const appName = identity.attributes.PhoneProductId;

  return new Promise(resolve => {
    const device = deployTool.findDevice(deployTarget);

    try {
      deployTool.uninstallAppPackage(appName, device);
    } catch (e) {
      console.log(chalk.yellow('Failed to uninstall app from ' + device.name));
    }

    const appxFile = glob.sync(path.join(appPackageFolder, '*.appx'))[0];
    try {
      console.log(chalk.white(deployTool.installAppPackage(appxFile, device, true, false)));
      resolve();
    } catch (e) {
      if (e.message.indexOf('Error code 2148734208 for command') !== -1) {
        console.log(chalk.white(deployTool.installAppPackage(appxFile, device, true, true)));
        resolve();
      } else {
        handleResponseError(e);
      }
    }
  });
}

function deployToDesktop(options) {
  const appPackageFolder = getAppPackage(options);
  const windowsStoreAppUtils = getWindowsStoreAppUtils(options);
  const appxManifest = getAppxManifest(options);
  const identity = appxManifest.root.children.filter(function (x) { return x.name === 'Identity'; })[0];
  const appName = identity.attributes.Name;
  const script = glob.sync(path.join(appPackageFolder, 'Add-AppDevPackage.ps1'))[0];

  return new Promise(resolve => {
    console.log(chalk.green('Removing old version of the app'));
    execSync(`powershell -ExecutionPolicy RemoteSigned Import-Module "${windowsStoreAppUtils}" ; Uninstall-App ${appName}`);

    console.log(chalk.green('Installing new version of the app'));
    execSync(`powershell -ExecutionPolicy RemoteSigned Import-Module "${windowsStoreAppUtils}"; Install-App "${script}"`);

    console.log(chalk.green('Starting the app'));
    execSync(`powershell -ExecutionPolicy RemoteSigned Import-Module "${windowsStoreAppUtils}"; Start-Locally ${appName}`);
    resolve();
  });
}

function startServerInNewWindow(options) {
  return new Promise(resolve => {
    http.get('http://localhost:8081/status', res => {
      if (res === 200) {
        console.log(chalk.green('React-Native Server already started'));
        resolve();
      }
    }).on('error', () => resolve(launchServer(options)));
  });
}

function launchServer(options) {
  console.log(chalk.green('Starting the React-Native Server'));
  const launchPackagerScript = path.join('node_modules/react-native/packager/launchPackager.bat');
  const opts = {
    cwd: options.root,
    detached: true,
    stdio: 'ignore'
  };

  return Promise.resolve(spawn('cmd.exe', ['/C', 'start', launchPackagerScript], opts));
}

module.exports = {
  deployToDesktop,
  deployToDevice,
  startServerInNewWindow
};
<|endoftext|>


<commit_before>module.exports = ['$rootScope', '$http', function ($rootScope, $http) {

    var config = {};
    var i18n = {
        current: "",
        data: {},
        available: [],
        currentState: "",
        active: false,
        previousLang: config.lang,
        stateLoaded: false
    };

    /**
     * Load your url from lazy mode
     * @return {String} url
     */
    function loadLazyDefaultUrl() {

        var url = config.url;
        if(config.lazy) {
            url = config.urls.filter(function (o) {
                return o.lang === config.lang;
            })[0].url;
        }
        return url;
    }

    /**
     * Build i18n.data.
     * @param  {Object} data Data from the translation file
     */
    function buildI18n(data) {

        if(!config.lazy) {
            i18n.data = data;
            return;
        }

        i18n.data[i18n.current] = data;
    }

    /**
     * Load a translation to the $scope
     * - doc BCP 47 {@link http://tools.ietf.org/html/bcp47}
     * - doc Value of HTML5 lang attr {@link http://webmasters.stackexchange.com/questions/28307/value-of-the-html5-lang-attribute}
     * @param {String} lang Your language cf BCP 47
     */
    function setTranslation(page) {

        page = page || config.state;

        // Prevent too many digest
        if(i18n.currentState === page && i18n.stateLoaded && i18n.current === i18n.previousLang) {
          return;
        }

        i18n.currentState = page;
        i18n.active = true;

        var lang = i18n.current;
        var common = {}, currentPageTranslation = {};

        if(i18n.data[lang]) {

            /**
             * Prevent the error
             *     > TypeError: Cannot read property '$$hashKey' of undefined
             * cf {@link https://github.com/dhoko/ngBabelfish/issues/5}
             */
            if(!i18n.data[lang][page]) {
                i18n.data[lang][page] = {};

                if(config.log) {
                    console.warn('[ngBabelfish-babelfish@setTranslation] No translation available for the page %s for the lang %s',page, lang);
                }
            }

            angular.extend(common, i18n.data[lang]._common);
            currentPageTranslation = angular.extend(common, i18n.data[lang][page]);

            if(config.namespace) {
                $rootScope[config.namespace] = currentPageTranslation;
            }else {
                angular.extend($rootScope, currentPageTranslation);
            }

            $rootScope.$emit('ngBabelfish.translation:loaded', {
                currentState: page,
                lang: lang
            });

            i18n.stateLoaded = true;
        }
    }

    /**
     * Load a translation to the $scope for a language
     * - doc BCP 47 {@link http://tools.ietf.org/html/bcp47}
     * - doc Value of HTML5 lang attr {@link http://webmasters.stackexchange.com/questions/28307/value-of-the-html5-lang-attribute}
     * @trigger {Event} i18n:babelfish:changed {previous:XXX,value:XXX2}
     * @param {String} lang Your language cf BCP 47
     */
    function loadLanguage(lang) {

        var old = document.documentElement.lang;

        if(!old) {
            old = 'en';
        }

        // Find the current lang if it doesn't exist. Store the previous one too
        if(!lang) {
            lang = old + '-' + old.toUpperCase();
            i18n.previousLang = lang;
        }else {
            document.documentElement.lang = lang.split('-')[0];
            i18n.previousLang = old + '-' + old.toUpperCase();
        }

        config.lang = i18n.current = lang;

        $rootScope.$emit('ngBabelfish.translation:changed', {
            previous: (old + '-' + old.toUpperCase()),
            value: lang
        });

        // Load the new language if we do not already have it
        if(config.lazy && !i18n.data[lang]) {
            service.load();
        }

    }

    // Listen when you change the language in your application
    $rootScope.$on('ngBabelfish.translation:changed', function() {
        setTranslation(i18n.currentState);
    });

    var service = {

        init: function init(customConfig) {
            config = customConfig;
        },

        load: function load(url, name) {

            url = url || loadLazyDefaultUrl();

            // Set the default lang for the html
            if(!document.documentElement.lang && config.lang) {
                document.documentElement.lang = config.lang.split('-')[0];
            }

            var lang = config.lang || document.documentElement.lang + '-' + document.documentElement.lang.toUpperCase();

            if(i18n.data[i18n.current]) {
                return;
            }
            return $http.get(url)
                .error(function() {
                    alert("Cannot load i18n translation file");
                })
                .success(function (data) {

                    if(config.lazy) {
                        config.current = name;
                    }
                    i18n.current = lang;
                    buildI18n(data);

                    if(config.lazy) {
                        i18n.available = config.urls.map(function (item) {return item.lang;});
                    }else {
                        i18n.available = Object.keys(i18n.data);
                    }
                })
                .then(function() {
                    setTranslation(i18n.currentState);
                });
        },

        /**
         * Return the current state translation
         * @param  {String} lang
         * @return {Object}
         */
        get: function get(lang) {
            var currentLang = i18n.data[lang || i18n.current] || {},
                common = {};

            if(!currentLang[i18n.currentState]) {

                if(config.log) {
                    console.warn('[ngBabelfish-babelfish@get] No translation available for the page %s for the  lang %s',i18n.currentState, (lang || i18n.current));
                }
                currentLang[i18n.currentState] = {};
            }

            angular.extend(common, {}, currentLang._common);
            return angular.extend(common, currentLang[i18n.currentState]);
        },

        /**
         * Get all translations available for a lang
         * @param  {String} lang
         * @return {Object}
         */
        all: function all(lang) {
            return i18n.data[lang || i18n.current];
        },

        /**
         * Return each translations available for your app
         * @return {Object}
         */
        translations: function translations() {
          return i18n.data;
        },

        /**
         * Get the current Language
         * @return {String} lang
         */
        current: function current() {
            return i18n.current;
        },

        /**
         * Update translations for a state
         * @param  {String} state
         */
        updateState: setTranslation,

        /**
         * Update the lang for the application
         * It will load a new language
         * @param  {String} lang
         */
        updateLang: loadLanguage,

        /**
         * Check if we have loaded i18n
         * @return {Boolean}
         */
        isLoaded: function isLoaded() {
            return i18n.active;
        },

        /**
         * List each languages available for the application
         * @return {Array}
         */
        available: function available(){
            return i18n.available;
        },

        /**
         * Return the default event name in order to listen a new state||route
         * @return {String}
         */
        getEvent: function getEvent() {
            return config.eventName;
        }
    };

    return service;
}];
<commit_msg>Remove useless file<commit_after><|endoftext|>


<commit_before>registerTest ('Has Google Analytics', {
    setup: function() {
        this.sourceCode = this.page.source;
        this.analyticsMatchString = "ga.js";
        this.analyticsMatchDummyString = "UA-XXXXX-X";
    },
    load : function() {
        this
        .test('Do we have a GA script tag',function($) {
            notEqual(this.sourceCode.indexOf(this.analyticsMatchString),-1,'We have a google analytics script tag');

        })
        .test( 'Do we have a valid GA ID (not UA-XXXXX-X)', function() {
            equal(this.sourceCode.indexOf(this.analyticsMatchDummyString),-1,'We have a google id that is different from dummy "UA-XXXXX-X"');
        });
    }
});
<commit_msg>adding question mark on the end of the test string<commit_after>registerTest ('Has Google Analytics', {
    setup: function() {
        this.sourceCode = this.page.source;
        this.analyticsMatchString = "ga.js";
        this.analyticsMatchDummyString = "UA-XXXXX-X";
    },
    load : function() {
        this
        .test('Do we have a GA script tag?',function($) {
            notEqual(this.sourceCode.indexOf(this.analyticsMatchString),-1,'We have a google analytics script tag');

        })
        .test( 'Do we have a valid GA ID (not UA-XXXXX-X)?', function() {
            equal(this.sourceCode.indexOf(this.analyticsMatchDummyString),-1,'We have a google id that is different from dummy "UA-XXXXX-X"');
        });
    }
});
<|endoftext|>


<commit_before>'use strict'
module.exports = {
	router:{
		test:'/test/router.js'
	},
	controller:{
		test:'test/controller/index.js'
	}
}<commit_msg>change config<commit_after>'use strict'
module.exports = {
	router:{
		movie:'/test/movie/router.js',
		list:'/test/list/router.js'
	},
	controller:{
		test:'test/controller/index.js'
	}
}<|endoftext|>


<commit_before>// Copyright (c) 2017, Roel Spilker. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

var deckDecoder = function() {
	var reader = function(encoded) {
		var index = 0;
		var bytes = atob(encoded);

		var _reader = {};
		_reader['nextByte'] = function() {
			return bytes.charCodeAt(index++);
		};

		_reader['nextVarInt'] = function() {
			var read = [];
			var next = 128;
			var result = 0;
			var multiplier = 1;
			while (next >= 128) {
				next = _reader.nextByte();
				read.push(next & 127);
			}
			for (var i = 0; i < read.length; i++) {
				result += read[i] * multiplier;
				multiplier *= 128;
			}
			return result;
		};
		return _reader;
	};

	var lookup = {};

	fetch('https://api.hearthstonejson.com/v1/latest/enUS/cards.collectible.json')
	.then(function(response) {
	  return response.json();
	})
	.then(function(data){
		for (var i = 0; i < data.length; i++) {
			lookup[data[i]['dbfId']] = data[i];
		}
	});

	var cardClasses = {
		'WARRIOR': 'Warrior',
		'HUNTER': 'Hunter',
		'DRUID': 'Druid',
		'MAGE': 'Mage',
		'PALADIN': 'Paladin',
		'PRIEST': 'Priest',
		'WARLOCK': 'Warlock',
		'ROGUE': 'Rogue',
		'SHAMAN': 'Shaman',
		'NEUTRAL': 'All Classes'
	};

	var resolve = function(deck, lookup) {
		var cards = [];
		for (var i = 0; i < deck.cards.length; i++) {
			cards.push({count: deck.cards[i].count, card: lookup[deck.cards[i].dbfId]})
		}
		cards.sort(function(a, b) {
			var result = a.card.cost - b.card.cost;
			if (result !== 0) {
				return result;
			}
			return (a.card.name > b.card.name) - (a.card.name < b.card.name);
		});
		return {heroClass: cardClasses[lookup[deck.hero].cardClass], type: (deck.type === 1 ? "Wild" : "Standard"), hero: lookup[deck.hero], cards: cards};
	};

	var deck = function(encoded) {
		var hero = null;
		var entries = [];
		var r = reader(encoded);
		r.nextByte();
		r.nextByte();
		var type = r.nextByte();
		var heroes = r.nextByte();
		for (var i = 0; i < heroes; i++) {
			hero = r.nextVarInt();
		}
		var singles = r.nextByte();
		for (var i = 0; i < singles; i++) {
			entries.push({ count: 1, dbfId: r.nextVarInt()});
		}
		var doubles = r.nextByte();
		for (var i = 0; i < doubles; i++) {
			entries.push({ count: 2, dbfId: r.nextVarInt()});
		}
		var multiples = r.nextByte();
		for (var i = 0; i < multiples; i++) {
			entries.push({ count: r.nextByte(), dbfId: r.nextVarInt()});
		}
		return { type: type, hero: hero, cards: entries};
	};

	// TODO: Make this a Promise so we can wait for the lookup to be completed.
	var decode = function(encoded) {
		return resolve(deck(encoded), lookup);
	};

	return {decode: decode};
};<commit_msg>read varint instead of byte<commit_after>// Copyright (c) 2017, Roel Spilker. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

var deckDecoder = function() {
	var reader = function(encoded) {
		var index = 0;
		var bytes = atob(encoded);

		var _reader = {};
		_reader['nextByte'] = function() {
			return bytes.charCodeAt(index++);
		};

		_reader['nextVarInt'] = function() {
			var read = [];
			var next = 128;
			var result = 0;
			var multiplier = 1;
			while (next >= 128) {
				next = _reader.nextByte();
				read.push(next & 127);
			}
			for (var i = 0; i < read.length; i++) {
				result += read[i] * multiplier;
				multiplier *= 128;
			}
			return result;
		};
		return _reader;
	};

	var lookup = {};

	fetch('https://api.hearthstonejson.com/v1/latest/enUS/cards.collectible.json')
	.then(function(response) {
	  return response.json();
	})
	.then(function(data){
		for (var i = 0; i < data.length; i++) {
			lookup[data[i]['dbfId']] = data[i];
		}
	});

	var cardClasses = {
		'WARRIOR': 'Warrior',
		'HUNTER': 'Hunter',
		'DRUID': 'Druid',
		'MAGE': 'Mage',
		'PALADIN': 'Paladin',
		'PRIEST': 'Priest',
		'WARLOCK': 'Warlock',
		'ROGUE': 'Rogue',
		'SHAMAN': 'Shaman',
		'NEUTRAL': 'All Classes'
	};

	var resolve = function(deck, lookup) {
		var cards = [];
		for (var i = 0; i < deck.cards.length; i++) {
			cards.push({count: deck.cards[i].count, card: lookup[deck.cards[i].dbfId]})
		}
		cards.sort(function(a, b) {
			var result = a.card.cost - b.card.cost;
			if (result !== 0) {
				return result;
			}
			return (a.card.name > b.card.name) - (a.card.name < b.card.name);
		});
		return {heroClass: cardClasses[lookup[deck.hero].cardClass], type: (deck.type === 1 ? "Wild" : "Standard"), hero: lookup[deck.hero], cards: cards};
	};

	var deck = function(encoded) {
		var hero = null;
		var entries = [];
		var r = reader(encoded);
		r.nextByte();
		r.nextVarInt();
		var type = r.nextVarInt();
		var heroes = r.nextVarInt();
		for (var i = 0; i < heroes; i++) {
			hero = r.nextVarInt();
		}
		var singles = r.nextVarInt();
		for (var i = 0; i < singles; i++) {
			entries.push({ count: 1, dbfId: r.nextVarInt()});
		}
		var doubles = r.nextVarInt();
		for (var i = 0; i < doubles; i++) {
			entries.push({ count: 2, dbfId: r.nextVarInt()});
		}
		var multiples = r.nextVarInt();
		for (var i = 0; i < multiples; i++) {
			entries.push({ count: r.nextVarInt(), dbfId: r.nextVarInt()});
		}
		return { type: type, hero: hero, cards: entries};
	};

	// TODO: Make this a Promise so we can wait for the lookup to be completed.
	var decode = function(encoded) {
		return resolve(deck(encoded), lookup);
	};

	return {decode: decode};
};<|endoftext|>


<commit_before>/* feature_rotate.js
 *
 * Does the feature rotate animation.
 */

var FEATURED_CHANNEL_WIDTH = 390;
var FEATURED_2_CHANNELS_WIDTH = 760;
var FEATURE_ROTATE_TIMEOUT = 15; // rotate timeout in seconds
var featureList = null;

function scheduleFeatureRotate() {
   loadHiddenScreenshots();
   if(!featureList) featureList = findFeatures();
   setTimeout(rotateFeatures, FEATURE_ROTATE_TIMEOUT * 1000);
}

function loadHiddenScreenshots() {
   var i = 1;
   while(true) {
     var screenshot = document.getElementById('feature-screenshot-' + i);
     i += 1;
     if(!screenshot) break;
     var fakeScreenshot = screenshot.childNodes[0];
     if(fakeScreenshot.nodeType != 3) continue;
     var re = /src:\s*"([^"]*)".*alt:\s*"([^"]*)"/
     var matches = re.exec(fakeScreenshot.nodeValue);
     if(!matches) continue;
     realScreenshot = new Image();
     realScreenshot.src = matches[1];
     realScreenshot.alt = matches[2];
     screenshot.replaceChild(realScreenshot, fakeScreenshot);
  }
}

function rotateFeatures() {
   FSStartX = FSCurrentFeature * FEATURED_CHANNEL_WIDTH;
   FSCurrentFeature = pickNextFeature();
   FSEndX = FSCurrentFeature * FEATURED_CHANNEL_WIDTH;
   FSTime = 0.0;
   animateFeatureScroll();
}

function pickNextFeature() {
   var nextFeature = FSCurrentFeature + 2*FSScrollDirection;
   if(nextFeature < 0) {
        FSScrollDirection *= -1;
        return 0
   }
   if(nextFeature >= featureList.length-2) {
        FSScrollDirection *= -1;
        return featureList.length-2;
   }
   return nextFeature;
}

function findFeatures() {
   var featuredList = document.getElementById('featured-list');
   var features = new Array();
   var currentFeature = featuredList.firstChild;
   if(currentFeature && currentFeature.nodeType != Node.ELEMENT_NODE)
      currentFeature = getNextElement(currentFeature);
   while(currentFeature) {
        features.push(currentFeature);
        currentFeature = getNextElement(currentFeature);
   }
   return features;
}

// Variables used in the feature scroll animation.  They are prefixed with FS to
// avoid namespace conflicts.
var FSStartX = 0;
var FSEndX = 0;
var FSTime = 0.0; // Time variable. ranges from 0 to 1.
var FSTimeStep = 0.1;
var FSTimeout = 50;
var FSCurrentFeature = 0;
var FSScrollDirection = 1;

function animateFeatureScroll() {
   if(FSTime < 1.0) {
       moveFeatureList(FSStartX + (FSEndX - FSStartX) * FSCalcPosition());
       FSTime += FSTimeStep;
       setTimeout(animateFeatureScroll, FSTimeout);
   } else {
       moveFeatureList(FSEndX);
       scheduleFeatureRotate();
   }
}

function moveFeatureList(leftX) {
   var featuredList = document.getElementById('featured-list');
   featuredList.style.left = '-' + leftX + 'px';
}

// Translates the feature scroll time into a position.  Ranges from 0 to 1,
// like FSTime, but gets transformed using a cosine for nice, non-linear
// movement.
function FSCalcPosition() {
  return (1 - Math.cos(FSTime * Math.PI)) / 2;
}
<commit_msg>Javascript fix for feature_rotate.js.<commit_after>/* feature_rotate.js
 *
 * Does the feature rotate animation.
 */

var FEATURED_CHANNEL_WIDTH = 390;
var FEATURED_2_CHANNELS_WIDTH = 760;
var FEATURE_ROTATE_TIMEOUT = 15; // rotate timeout in seconds
var featureList = null;

function scheduleFeatureRotate() {
   loadHiddenScreenshots();
   if(!featureList) featureList = findFeatures();
   setTimeout(rotateFeatures, FEATURE_ROTATE_TIMEOUT * 1000);
}

function loadHiddenScreenshots() {
   var i = 1;
   while(true) {
     var screenshot = document.getElementById('feature-screenshot-' + i);
     i += 1;
     if(!screenshot) break;
     var fakeScreenshot = screenshot.childNodes[0];
     if(fakeScreenshot.nodeType != 3) continue;
     var re = /src:\s*"([^"]*)".*alt:\s*"([^"]*)"/
     var matches = re.exec(fakeScreenshot.nodeValue);
     if(!matches) continue;
     var realScreenshot = new Image();
     realScreenshot.src = matches[1];
     realScreenshot.alt = matches[2];
     screenshot.replaceChild(realScreenshot, fakeScreenshot);
  }
}

function rotateFeatures() {
   FSStartX = FSCurrentFeature * FEATURED_CHANNEL_WIDTH;
   FSCurrentFeature = pickNextFeature();
   FSEndX = FSCurrentFeature * FEATURED_CHANNEL_WIDTH;
   FSTime = 0.0;
   animateFeatureScroll();
}

function pickNextFeature() {
   var nextFeature = FSCurrentFeature + 2*FSScrollDirection;
   if(nextFeature < 0) {
        FSScrollDirection *= -1;
        return 0
   }
   if(nextFeature >= featureList.length-2) {
        FSScrollDirection *= -1;
        return featureList.length-2;
   }
   return nextFeature;
}

function findFeatures() {
   var featuredList = document.getElementById('featured-list');
   var features = new Array();
   var currentFeature = featuredList.firstChild;
   if(currentFeature && currentFeature.nodeType != Node.ELEMENT_NODE)
      currentFeature = getNextElement(currentFeature);
   while(currentFeature) {
        features.push(currentFeature);
        currentFeature = getNextElement(currentFeature);
   }
   return features;
}

// Variables used in the feature scroll animation.  They are prefixed with FS to
// avoid namespace conflicts.
var FSStartX = 0;
var FSEndX = 0;
var FSTime = 0.0; // Time variable. ranges from 0 to 1.
var FSTimeStep = 0.1;
var FSTimeout = 50;
var FSCurrentFeature = 0;
var FSScrollDirection = 1;

function animateFeatureScroll() {
   if(FSTime < 1.0) {
       moveFeatureList(FSStartX + (FSEndX - FSStartX) * FSCalcPosition());
       FSTime += FSTimeStep;
       setTimeout(animateFeatureScroll, FSTimeout);
   } else {
       moveFeatureList(FSEndX);
       scheduleFeatureRotate();
   }
}

function moveFeatureList(leftX) {
   var featuredList = document.getElementById('featured-list');
   featuredList.style.left = '-' + leftX + 'px';
}

// Translates the feature scroll time into a position.  Ranges from 0 to 1,
// like FSTime, but gets transformed using a cosine for nice, non-linear
// movement.
function FSCalcPosition() {
  return (1 - Math.cos(FSTime * Math.PI)) / 2;
}
<|endoftext|>


<commit_before>"use strict";

var spawn = require('win-spawn')
  , through = require('through')
  , path = require('path')
  , fs = require('fs')
  , _ = require('underscore')
  , glob = require('glob')
  , logger = require('../../server/logger.js').get('appium');

// Date-Utils: Polyfills for the Date object
require('date-utils');

var IosLog = function (opts) {
  this.udid = opts.udid;
  this.xcodeVersion = opts.xcodeVersion;
  this.debugMode = opts.debug;
  this.debugTrace = opts.debugTrace;
  this.proc = null;
  this.onIosLogStart = null;
  this.iosLogStarted = false;
  this.iosLogStartTime = null;
  this.calledBack = false;
  this.logs = [];
  this.logRow = "";
  this.logsSinceLastRequest = [];

  if (this.xcodeVersion === null) {
    logger.warn("Xcode version passed into log capture code as null, assuming Xcode 5");
    this.xcodeVersion = '5.0';
  }

};

IosLog.prototype.debug = function (msg) {
  if (this.debugMode) {
    var log = "[IOS_SYSLOG_CAPTURE] " + msg;
    logger.debug(log.grey);
  }
};

IosLog.prototype.startCapture = function (cb) {
  this.onIosLogStart = cb;
  // Select cmd for log capture
  if (this.udid) {
    var spawnEnv = _.clone(process.env);
    var limdDir = path.resolve(__dirname,
                               "../../../build/libimobiledevice-macosx/");
    spawnEnv.PATH = process.env.PATH + ":" + limdDir;
    spawnEnv.DYLD_LIBRARY_PATH = limdDir + ":" + process.env.DYLD_LIBRARY_PATH;
    logger.info("Starting iOS device log capture via idevicesyslog");
    this.proc = spawn("idevicesyslog", ["-u", this.udid], {env: spawnEnv});
    this.finishStartingLogCapture(cb);
  } else {
    if (parseInt(this.xcodeVersion.split(".")[0], 10) >= 5) {
      logger.info("Starting iOS 7.* simulator log capture");
      var sim7LogsPath = path.resolve(process.env.HOME, "Library", "Logs", "iOS Simulator");
      glob(sim7LogsPath + "/7.*/system.log", function (err, files) {
        if (err || files.length < 1) {
          logger.error("Could not start log capture because no iOS 7 " +
            "simulator logs could be found at " + sim7LogsPath + "/7.*. " +
            "Logging will not be functional for this run");
          return cb();
        } else {
          var lastModifiedLogPath = files[0]
            , lastModifiedLogTime = fs.statSync(files[0]).mtime;
          _.each(files, function (file) {
            var mtime = fs.statSync(file).mtime;
            if (mtime > lastModifiedLogTime) {
              lastModifiedLogPath = file;
              lastModifiedLogTime = mtime;
            }
          });
          this.proc = spawn("tail", ["-f", "-n", "1", lastModifiedLogPath]);
          // -n 1 is used so that tail returns a line that lets this process know that the
          // first line returned wasn't from stderr so it can tell the tailing was successful
          this.finishStartingLogCapture(cb);
        }
      }.bind(this));
    } else {
      logger.info("Starting iOS 6.* simulator log capture");
      this.proc = spawn("tail", ["-f", "-n", "1", "/var/log/system.log"]);
      this.finishStartingLogCapture(cb);
    }
  }
};

IosLog.prototype.finishStartingLogCapture = function (cb) {
  this.proc.stdout.setEncoding('utf8');
  this.proc.stderr.setEncoding('utf8');
  this.proc.on('error', function (err) {
    logger.error("iOS log capture failed: " + err.message);
    if (!this.calledBack) {
      this.calledBack = true;
      cb(err);
    }
  }.bind(this));
  this.proc.stdout.pipe(through(this.onStdout.bind(this)));
  this.proc.stderr.pipe(through(this.onStderr.bind(this)));
};

IosLog.prototype.stopCapture = function () {
  logger.info("Stopping iOS log capture");
  this.proc.kill();
  this.proc = null;
};

IosLog.prototype.onStdout = function (data) {
  if (!this.calledBack) {
    // don't store the first line of the log because it came before the sim or device was launched
    this.onOutput(data);
  } else {
    this.logRow += data;
    if (data.substr(-1, 1) === "\n") {
      this.onOutput(data, "");
      this.logRow = "";
    }
  }
};

IosLog.prototype.onStderr = function (data) {
  if (/execvp\(\)/.test(data)) {
    logger.error("iOS log capture process failed to start");
    if (!this.calledBack) {
      this.calledBack = true;
      this.onIosLogStart(new Error("iOS log capture process failed to start"));
      return;
    }
  }
  this.onOutput(data, ' STDERR');
};

IosLog.prototype.onOutput = function (data, prefix) {
  if (!this.iosLogStarted) {
    this.iosLogStarted = true;
    this.iosLogStartTime = new Date();
    if (!this.calledBack) {
      this.calledBack = true;
      this.onIosLogStart();
    }
  }
  var logs = this.logRow.split("\n");
  _.each(logs, function (log) {
    log = log.trim();
    if (log) {
      // Filter old log rows
      var logRowParts = log.split(" ");
      var logRowDate = new Date(
        Date.parse(this.iosLogStartTime.getFullYear() + " " + logRowParts[0] + " " + logRowParts[1] + " " + logRowParts[2])
      );
      if (!this.udid || logRowDate.isAfter(this.iosLogStartTime)) {
        var logObj = {
          timestamp: Date.now()
        , level: 'ALL'
        , message: log
        };
        this.logs.push(logObj);
        this.logsSinceLastRequest.push(logObj);
        if (this.debugMode || this.debugTrace) {
          logger.debug('[IOS_SYSLOG_ROW ' + prefix + '] ' + log);
        }
      }
    }
  }.bind(this));
};

IosLog.prototype.getLogs = function () {
  var ret = this.logsSinceLastRequest;
  this.logsSinceLastRequest = [];
  return ret;
};

IosLog.prototype.getAllLogs = function () {
  return this.logs;
};

module.exports = function (opts) {
  return new IosLog(opts);
};
<commit_msg>Adding state flag so device/simulator system.log lines that do not have dates do not always get filtered out even if they are new log lines.<commit_after>"use strict";

var spawn = require('win-spawn')
  , through = require('through')
  , path = require('path')
  , fs = require('fs')
  , _ = require('underscore')
  , glob = require('glob')
  , logger = require('../../server/logger.js').get('appium');

// Date-Utils: Polyfills for the Date object
require('date-utils');

var IosLog = function (opts) {
  this.udid = opts.udid;
  this.xcodeVersion = opts.xcodeVersion;
  this.debugMode = opts.debug;
  this.debugTrace = opts.debugTrace;
  this.proc = null;
  this.onIosLogStart = null;
  this.iosLogStarted = false;
  this.iosLogStartTime = null;
  this.calledBack = false;
  this.loggingModeOn = true;
  this.logs = [];
  this.logRow = "";
  this.logsSinceLastRequest = [];

  if (this.xcodeVersion === null) {
    logger.warn("Xcode version passed into log capture code as null, assuming Xcode 5");
    this.xcodeVersion = '5.0';
  }

};

IosLog.prototype.debug = function (msg) {
  if (this.debugMode) {
    var log = "[IOS_SYSLOG_CAPTURE] " + msg;
    logger.debug(log.grey);
  }
};

IosLog.prototype.startCapture = function (cb) {
  this.onIosLogStart = cb;
  // Select cmd for log capture
  if (this.udid) {
    var spawnEnv = _.clone(process.env);
    var limdDir = path.resolve(__dirname,
                               "../../../build/libimobiledevice-macosx/");
    spawnEnv.PATH = process.env.PATH + ":" + limdDir;
    spawnEnv.DYLD_LIBRARY_PATH = limdDir + ":" + process.env.DYLD_LIBRARY_PATH;
    logger.info("Starting iOS device log capture via idevicesyslog");
    // idevicesyslog retrieves many old device log lines that came before it was
    // started so filter those out until we encounter new log lines.
    this.loggingModeOn = false;
    this.proc = spawn("idevicesyslog", ["-u", this.udid], {env: spawnEnv});
    this.finishStartingLogCapture(cb);
  } else {
    if (parseInt(this.xcodeVersion.split(".")[0], 10) >= 5) {
      logger.info("Starting iOS 7.* simulator log capture");
      var sim7LogsPath = path.resolve(process.env.HOME, "Library", "Logs", "iOS Simulator");
      glob(sim7LogsPath + "/7.*/system.log", function (err, files) {
        if (err || files.length < 1) {
          logger.error("Could not start log capture because no iOS 7 " +
            "simulator logs could be found at " + sim7LogsPath + "/7.*. " +
            "Logging will not be functional for this run");
          return cb();
        } else {
          var lastModifiedLogPath = files[0]
            , lastModifiedLogTime = fs.statSync(files[0]).mtime;
          _.each(files, function (file) {
            var mtime = fs.statSync(file).mtime;
            if (mtime > lastModifiedLogTime) {
              lastModifiedLogPath = file;
              lastModifiedLogTime = mtime;
            }
          });
          this.proc = spawn("tail", ["-f", "-n", "1", lastModifiedLogPath]);
          // -n 1 is used so that tail returns a line that lets this process know that the
          // first line returned wasn't from stderr so it can tell the tailing was successful
          this.finishStartingLogCapture(cb);
        }
      }.bind(this));
    } else {
      logger.info("Starting iOS 6.* simulator log capture");
      this.proc = spawn("tail", ["-f", "-n", "1", "/var/log/system.log"]);
      this.finishStartingLogCapture(cb);
    }
  }
};

IosLog.prototype.finishStartingLogCapture = function (cb) {
  this.proc.stdout.setEncoding('utf8');
  this.proc.stderr.setEncoding('utf8');
  this.proc.on('error', function (err) {
    logger.error("iOS log capture failed: " + err.message);
    if (!this.calledBack) {
      this.calledBack = true;
      cb(err);
    }
  }.bind(this));
  this.proc.stdout.pipe(through(this.onStdout.bind(this)));
  this.proc.stderr.pipe(through(this.onStderr.bind(this)));
};

IosLog.prototype.stopCapture = function () {
  logger.info("Stopping iOS log capture");
  this.proc.kill();
  this.proc = null;
};

IosLog.prototype.onStdout = function (data) {
  if (!this.calledBack) {
    // don't store the first line of the log because it came before the sim or device was launched
    this.onOutput(data);
  } else {
    this.logRow += data;
    if (data.substr(-1, 1) === "\n") {
      this.onOutput(data, "");
      this.logRow = "";
    }
  }
};

IosLog.prototype.onStderr = function (data) {
  if (/execvp\(\)/.test(data)) {
    logger.error("iOS log capture process failed to start");
    if (!this.calledBack) {
      this.calledBack = true;
      this.onIosLogStart(new Error("iOS log capture process failed to start"));
      return;
    }
  }
  this.onOutput(data, ' STDERR');
};

IosLog.prototype.onOutput = function (data, prefix) {
  if (!this.iosLogStarted) {
    this.iosLogStarted = true;
    this.iosLogStartTime = new Date();
    if (!this.calledBack) {
      this.calledBack = true;
      this.onIosLogStart();
    }
  }
  var logs = this.logRow.split("\n");
  _.each(logs, function (log) {
    log = log.trim();
    if (log) {
      // Turn logging on when the 1st row that has a new date comes through.
      // - Some system.log lines do not have a leading date and therefore never pass the
      //   logRowDate.isAfter(this.iosLogStartTime) check so we require a state flag here,
      //   otherwise all the lines without dates get filtered out even if they are new.
      if (!this.loggingModeOn) {
        var logRowParts = log.split(" ");
        var logRowDate = new Date(
          Date.parse(this.iosLogStartTime.getFullYear() + " " + logRowParts[0] + " " + logRowParts[1] + " " + logRowParts[2])
        );
        if (logRowDate.isAfter(this.iosLogStartTime)) {
          this.loggingModeOn = true;
        }
      }
      if (this.loggingModeOn) {
        var logObj = {
          timestamp: Date.now()
        , level: 'ALL'
        , message: log
        };
        this.logs.push(logObj);
        this.logsSinceLastRequest.push(logObj);
        if (this.debugMode || this.debugTrace) {
          logger.debug('[IOS_SYSLOG_ROW ' + prefix + '] ' + log);
        }
      }
    }
  }.bind(this));
};

IosLog.prototype.getLogs = function () {
  var ret = this.logsSinceLastRequest;
  this.logsSinceLastRequest = [];
  return ret;
};

IosLog.prototype.getAllLogs = function () {
  return this.logs;
};

module.exports = function (opts) {
  return new IosLog(opts);
};
<|endoftext|>


<commit_before>var Emitter = require( 'async-emitter' )
var inherit = require( 'bloodline' )

/**
 * World
 * @constructor
 * @param {Object} options
 *   @property {Number} timeStep dt
 * @return {World}
 */
function World( options ) {

  if( !(this instanceof World) )
    return new World( options )

  Emitter.call( this )

  options = options != null ?
    options : {}

  // Fixed time step
  this.timeStep = options.timeStep || ( 1 / 60 )
  // Maximum sub steps
  this.maxSubSteps = options.maxSubSteps || 10

  // Last used timestep
  this.dt = -1
  // Wall-clock time since simulation start
  this.time = 0
  // Time accumulator for interpolation
  // @see http://gafferongames.com/game-physics/fix-your-timestep/
  this.accumulator = 0

  // Objects in the world
  this.objects = []

}

/**
 * World prototype
 * @type {Object}
 */
World.prototype = {

  constructor: World,

  get objectCount() {
    return this.objects.length
  },

  add: function( body ) {
    this.emit( 'add', body )
  },

  remove: function( body ) {
    this.emit( 'remove', body )
  },

  // TODO: Figure out how to do time acceleration
  step: function( dt, timeStep, maxSubSteps ) {

    timeStep = timeStep || this.timeStep
    maxSubSteps = maxSubSteps || this.maxSubSteps

    if( dt >= maxSubSteps * timeStep ) {
      console.warn( 'Losing simulation time, delta is too low' )
    }

    if( dt === 0 ) {

      // Fixed time stepping
      this.integrate( dt )
      this.time = this.time + timeStep

    } else {

      var subSteps = 0

      // Dynamic substepping
      this.accumulator = this.accumulator + dt

      // Do fixed steps to catch up
      while( this.accumulator >= dt && subSteps < maxSubSteps ) {
        this.integrate( dt )
        this.accumulator = this.accumulator - dt
        subSteps++
      }

      var t = ( this.accumulator % dt ) / dt

      for( var i = 0; i < this.objects.length; i++ ) {
        // TODO: (S)LERP body positions & rotation
        // (s)lerp( current, t, interpolated )
      }

      this.time = this.time + dt

    }

  },

  integrate: function( dt ) {
    // TODO
  },

}

inherit( World, Emitter )
// Exports
module.exports = World
<commit_msg>Update lib/world: Split up stepping methods<commit_after>var Zero = require( './zero' )
var Emitter = require( 'async-emitter' )
var inherit = require( 'bloodline' )

/**
 * World
 * @constructor
 * @param {Object} options
 *   @property {Number} timeStep dt
 * @return {World}
 */
function World( options ) {

  if( !(this instanceof World) )
    return new World( options )

  Emitter.call( this )

  options = options != null ?
    options : {}

  // Fixed time step
  this.timeStep = options.timeStep || ( 1 / 60 )
  // Maximum sub steps
  this.maxSubSteps = options.maxSubSteps || 10

  // Last used timestep
  this.dt = -1
  // Wall-clock time since simulation start
  this.time = 0
  // Time accumulator for interpolation
  // @see http://gafferongames.com/game-physics/fix-your-timestep/
  this.accumulator = 0

  // Objects in the world
  this.objects = []

  this.integrator = options.integrator ||
    new Zero.Integrator.Simple( this, options )

}

/**
 * World prototype
 * @type {Object}
 */
World.prototype = {

  constructor: World,

  get objectCount() {
    return this.objects.length
  },

  // TODO: Reason about naming
  addObject: function( body ) {
    this.objects.push( body )
    this.emit( 'add', body )
  },

  removeObject: function( body ) {

    var index = this.objects.indexOf( body )

    if( ~index ) {
      this.objects.splice( index, 1 )
    }

    this.emit( 'remove', body )

  },

  // TODO: Figure out how to do time acceleration
  step: function( dt, timeStep, maxSubSteps ) {

    timeStep = timeStep || this.timeStep
    maxSubSteps = maxSubSteps || this.maxSubSteps

    timeStep !== 0 ?
      this.integrate( dt, timeStep, maxSubSteps ) :
      this.integrateStep( dt, timeStep )

  },

  interpolate: function( dt ) {

    var t = ( this.accumulator % dt ) / dt

    // TODO: (S)LERP body positions & rotation
    // (s)lerp( current, t, interpolated )
    for( var i = 0; i < this.objects.length; i++ ) {

      this.objects[i].previousPosition.lerp(
        this.objects[i].position, t,
        this.objects[i].interpolatedPosition
      )

      this.objects[i].previousQuaternion.slerp(
        this.objects[i].quaternion, t,
        this.objects[i].interpolatedQuaternion
      )

      this.objects[i].previousQuaternion.normalize()

    }

  },

  integrateStep: function( dt, timeStep ) {
    // Fixed time stepping
    this.integrator.step( dt )
    this.time += timeStep
  },

  integrate: function( dt, timeStep, maxSubSteps ) {

    // TODO: Thoroughly understand this
    if( dt >= maxSubSteps * timeStep ) {
      console.warn( 'Losing simulation time, delta is too low' )
    }

    var subSteps = 0

    // Dynamic substepping
    this.accumulator += dt

    // Do fixed steps to catch up
    while( this.accumulator >= dt && subSteps < maxSubSteps ) {
      this.integrator.step( dt )
      this.accumulator -= dt
      subSteps++
    }

    this.interpolate( dt )
    this.time += dt

  },

  clearForces: function() {
    for( var i = 0; i !== this.objects.length; i++ ) {
      this.objects[i].force.set( 0, 0, 0 )
      this.objects[i].torque.set( 0, 0, 0 )
    }
  },

}

inherit( World, Emitter )
// Exports
module.exports = World
<|endoftext|>