<commit_before>/**
 * Copyright 2018-present Facebook.
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 * @format
 * @flow strict-local
 */

const path = require('path');
const fs = require('fs');
const Metro = require('metro');
const util = require('util');
const recursiveReaddir = require('recursive-readdir');
const expandTilde = require('expand-tilde');
const HOME_DIR = require('os').homedir();

/* eslint-disable prettier/prettier */
/*::
type CompileOptions = {|
  force: boolean,
  failSilently: boolean,
|};
*/

const DEFAULT_COMPILE_OPTIONS /*: CompileOptions */ = {
  force: false,
  failSilently: true,
};

module.exports = async (
  reloadCallback,
  pluginPaths,
  pluginCache,
  options = DEFAULT_COMPILE_OPTIONS,
) => {
  const plugins = pluginEntryPoints(pluginPaths);
  if (!fs.existsSync(pluginCache)) {
    fs.mkdirSync(pluginCache);
  }
  watchChanges(plugins, reloadCallback, pluginCache, options);
  const dynamicPlugins = [];
  for (const plugin of Object.values(plugins)) {
    const dynamicOptions = Object.assign(options, {force: false});
    const compiledPlugin = await compilePlugin(
      plugin,
      pluginCache,
      dynamicOptions,
    );
    if (compiledPlugin) {
      dynamicPlugins.push(compiledPlugin);
    }
  }
  console.log('✅  Compiled all plugins.');
  return dynamicPlugins;
};

function watchChanges(
  plugins,
  reloadCallback,
  pluginCache,
  options = DEFAULT_COMPILE_OPTIONS,
) {
  // eslint-disable-next-line no-console
  console.log('🕵  Watching for plugin changes');

  let delayedCompilation = {};
  const kCompilationDelayMillis = 1000;

  Object.values(plugins).map(plugin =>
    fs.watch(plugin.rootDir, {recursive: true}, (eventType, filename) => {
      // only recompile for changes in not hidden files. Watchman might create
      // a file called .watchman-cookie
      if (!filename.startsWith('.') && !delayedCompilation[plugin.name]) {
        delayedCompilation[plugin.name] = setTimeout(() => {
          delayedCompilation[plugin.name] = null;
          // eslint-disable-next-line no-console
          console.log(`🕵  Detected changes in ${plugin.name}`);
          const watchOptions = Object.assign(options, {force: true});
          compilePlugin(plugin, pluginCache, watchOptions).then(reloadCallback);
        }, kCompilationDelayMillis);
      }
    }),
  );
}
function hash(string) {
  let hash = 0;
  if (string.length === 0) {
    return hash;
  }
  let chr;
  for (let i = 0; i < string.length; i++) {
    chr = string.charCodeAt(i);
    hash = (hash << 5) - hash + chr;
    hash |= 0;
  }
  return hash;
}
const fileToIdMap = new Map();
const createModuleIdFactory = () => filePath => {
  if (filePath === '__prelude__') {
    return 0;
  }
  let id = fileToIdMap.get(filePath);
  if (typeof id !== 'number') {
    id = hash(filePath);
    fileToIdMap.set(filePath, id);
  }
  return id;
};
function pluginEntryPoints(additionalPaths = []) {
  const defaultPluginPath = path.join(HOME_DIR, '.flipper', 'node_modules');
  const entryPoints = entryPointForPluginFolder(defaultPluginPath);
  if (typeof additionalPaths === 'string') {
    additionalPaths = [additionalPaths];
  }
  additionalPaths.forEach(additionalPath => {
    const additionalPlugins = entryPointForPluginFolder(additionalPath);
    Object.keys(additionalPlugins).forEach(key => {
      entryPoints[key] = additionalPlugins[key];
    });
  });
  return entryPoints;
}
function entryPointForPluginFolder(pluginPath) {
  pluginPath = expandTilde(pluginPath);
  if (!fs.existsSync(pluginPath)) {
    return {};
  }
  return fs
    .readdirSync(pluginPath)
    .filter(name =>
      /*name.startsWith('flipper-plugin') && */ fs
        .lstatSync(path.join(pluginPath, name))
        .isDirectory(),
    )
    .filter(Boolean)
    .map(name => {
      let packageJSON;
      try {
        packageJSON = fs
          .readFileSync(path.join(pluginPath, name, 'package.json'))
          .toString();
      } catch (e) {}
      if (packageJSON) {
        try {
          const pkg = JSON.parse(packageJSON);
          return {
            packageJSON: pkg,
            name: pkg.name,
            entry: path.join(pluginPath, name, pkg.main || 'index.js'),
            rootDir: path.join(pluginPath, name),
          };
        } catch (e) {
          console.error(
            `Could not load plugin "${pluginPath}", because package.json is invalid.`,
          );
          console.error(e);
          return null;
        }
      }
    })
    .filter(Boolean)
    .reduce((acc, cv) => {
      acc[cv.name] = cv;
      return acc;
    }, {});
}
function mostRecentlyChanged(dir) {
  return util
    .promisify(recursiveReaddir)(dir)
    .then(files =>
      files
        .map(f => fs.lstatSync(f).ctime)
        .reduce((a, b) => (a > b ? a : b), new Date(0)),
    );
}
async function compilePlugin(
  {rootDir, name, entry, packageJSON},
  pluginCache,
  options/*: CompileOptions */,
) {
  const fileName = `${name}@${packageJSON.version || '0.0.0'}.js`;
  const out = path.join(pluginCache, fileName);
  const result = Object.assign({}, packageJSON, {rootDir, name, entry, out});
  // check if plugin needs to be compiled
  const rootDirCtime = await mostRecentlyChanged(rootDir);
  if (
    !options.force &&
    fs.existsSync(out) &&
    rootDirCtime < fs.lstatSync(out).ctime
  ) {
    // eslint-disable-next-line no-console
    console.log(`🥫  Using cached version of ${name}...`);
    return result;
  } else {
    console.log(`⚙  Compiling ${name}...`); // eslint-disable-line no-console
    try {
      await Metro.runBuild(
        {
          reporter: {update: () => {}},
          projectRoot: rootDir,
          watchFolders: [__dirname, rootDir],
          serializer: {
            getRunModuleStatement: moduleID =>
              `module.exports = global.__r(${moduleID}).default;`,
            createModuleIdFactory,
          },
          transformer: {
            babelTransformerPath: path.join(
              __dirname,
              'transforms',
              'index.js',
            ),
          },
          resolver: {
            blacklistRE: /\/(sonar|flipper-public)\/dist\//,
          },
        },
        {
          entry: entry.replace(rootDir, '.'),
          out,
          dev: false,
          sourceMap: true,
          minify: false,
        },
      );
    } catch (e) {
      if (options.failSilently) {
        console.error(
          `❌  Plugin ${name} is ignored, because it could not be compiled.`,
        );
        console.error(e);
        return null;
      } else {
        throw e;
      }
    }
    return result;
  }
}
<commit_msg>Fix lint<commit_after>/**
 * Copyright 2018-present Facebook.
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 * @format
 * @flow strict-local
 */

const path = require('path');
const fs = require('fs');
const Metro = require('metro');
const util = require('util');
const recursiveReaddir = require('recursive-readdir');
const expandTilde = require('expand-tilde');
const HOME_DIR = require('os').homedir();

/* eslint-disable prettier/prettier */
/*::
type CompileOptions = {|
  force: boolean,
  failSilently: boolean,
|};
*/

const DEFAULT_COMPILE_OPTIONS /*: CompileOptions */ = {
  force: false,
  failSilently: true,
};

module.exports = async (
  reloadCallback,
  pluginPaths,
  pluginCache,
  options = DEFAULT_COMPILE_OPTIONS,
) => {
  const plugins = pluginEntryPoints(pluginPaths);
  if (!fs.existsSync(pluginCache)) {
    fs.mkdirSync(pluginCache);
  }
  watchChanges(plugins, reloadCallback, pluginCache, options);
  const dynamicPlugins = [];
  for (const plugin of Object.values(plugins)) {
    const dynamicOptions = Object.assign(options, {force: false});
    const compiledPlugin = await compilePlugin(
      plugin,
      pluginCache,
      dynamicOptions,
    );
    if (compiledPlugin) {
      dynamicPlugins.push(compiledPlugin);
    }
  }
  console.log('✅  Compiled all plugins.');
  return dynamicPlugins;
};

function watchChanges(
  plugins,
  reloadCallback,
  pluginCache,
  options = DEFAULT_COMPILE_OPTIONS,
) {
  // eslint-disable-next-line no-console
  console.log('🕵  Watching for plugin changes');

  const delayedCompilation = {};
  const kCompilationDelayMillis = 1000;

  Object.values(plugins).map(plugin =>
    fs.watch(plugin.rootDir, {recursive: true}, (eventType, filename) => {
      // only recompile for changes in not hidden files. Watchman might create
      // a file called .watchman-cookie
      if (!filename.startsWith('.') && !delayedCompilation[plugin.name]) {
        delayedCompilation[plugin.name] = setTimeout(() => {
          delayedCompilation[plugin.name] = null;
          // eslint-disable-next-line no-console
          console.log(`🕵  Detected changes in ${plugin.name}`);
          const watchOptions = Object.assign(options, {force: true});
          compilePlugin(plugin, pluginCache, watchOptions).then(reloadCallback);
        }, kCompilationDelayMillis);
      }
    }),
  );
}
function hash(string) {
  let hash = 0;
  if (string.length === 0) {
    return hash;
  }
  let chr;
  for (let i = 0; i < string.length; i++) {
    chr = string.charCodeAt(i);
    hash = (hash << 5) - hash + chr;
    hash |= 0;
  }
  return hash;
}
const fileToIdMap = new Map();
const createModuleIdFactory = () => filePath => {
  if (filePath === '__prelude__') {
    return 0;
  }
  let id = fileToIdMap.get(filePath);
  if (typeof id !== 'number') {
    id = hash(filePath);
    fileToIdMap.set(filePath, id);
  }
  return id;
};
function pluginEntryPoints(additionalPaths = []) {
  const defaultPluginPath = path.join(HOME_DIR, '.flipper', 'node_modules');
  const entryPoints = entryPointForPluginFolder(defaultPluginPath);
  if (typeof additionalPaths === 'string') {
    additionalPaths = [additionalPaths];
  }
  additionalPaths.forEach(additionalPath => {
    const additionalPlugins = entryPointForPluginFolder(additionalPath);
    Object.keys(additionalPlugins).forEach(key => {
      entryPoints[key] = additionalPlugins[key];
    });
  });
  return entryPoints;
}
function entryPointForPluginFolder(pluginPath) {
  pluginPath = expandTilde(pluginPath);
  if (!fs.existsSync(pluginPath)) {
    return {};
  }
  return fs
    .readdirSync(pluginPath)
    .filter(name =>
      /*name.startsWith('flipper-plugin') && */ fs
        .lstatSync(path.join(pluginPath, name))
        .isDirectory(),
    )
    .filter(Boolean)
    .map(name => {
      let packageJSON;
      try {
        packageJSON = fs
          .readFileSync(path.join(pluginPath, name, 'package.json'))
          .toString();
      } catch (e) {}
      if (packageJSON) {
        try {
          const pkg = JSON.parse(packageJSON);
          return {
            packageJSON: pkg,
            name: pkg.name,
            entry: path.join(pluginPath, name, pkg.main || 'index.js'),
            rootDir: path.join(pluginPath, name),
          };
        } catch (e) {
          console.error(
            `Could not load plugin "${pluginPath}", because package.json is invalid.`,
          );
          console.error(e);
          return null;
        }
      }
    })
    .filter(Boolean)
    .reduce((acc, cv) => {
      acc[cv.name] = cv;
      return acc;
    }, {});
}
function mostRecentlyChanged(dir) {
  return util
    .promisify(recursiveReaddir)(dir)
    .then(files =>
      files
        .map(f => fs.lstatSync(f).ctime)
        .reduce((a, b) => (a > b ? a : b), new Date(0)),
    );
}
async function compilePlugin(
  {rootDir, name, entry, packageJSON},
  pluginCache,
  options/*: CompileOptions */,
) {
  const fileName = `${name}@${packageJSON.version || '0.0.0'}.js`;
  const out = path.join(pluginCache, fileName);
  const result = Object.assign({}, packageJSON, {rootDir, name, entry, out});
  // check if plugin needs to be compiled
  const rootDirCtime = await mostRecentlyChanged(rootDir);
  if (
    !options.force &&
    fs.existsSync(out) &&
    rootDirCtime < fs.lstatSync(out).ctime
  ) {
    // eslint-disable-next-line no-console
    console.log(`🥫  Using cached version of ${name}...`);
    return result;
  } else {
    console.log(`⚙  Compiling ${name}...`); // eslint-disable-line no-console
    try {
      await Metro.runBuild(
        {
          reporter: {update: () => {}},
          projectRoot: rootDir,
          watchFolders: [__dirname, rootDir],
          serializer: {
            getRunModuleStatement: moduleID =>
              `module.exports = global.__r(${moduleID}).default;`,
            createModuleIdFactory,
          },
          transformer: {
            babelTransformerPath: path.join(
              __dirname,
              'transforms',
              'index.js',
            ),
          },
          resolver: {
            blacklistRE: /\/(sonar|flipper-public)\/dist\//,
          },
        },
        {
          entry: entry.replace(rootDir, '.'),
          out,
          dev: false,
          sourceMap: true,
          minify: false,
        },
      );
    } catch (e) {
      if (options.failSilently) {
        console.error(
          `❌  Plugin ${name} is ignored, because it could not be compiled.`,
        );
        console.error(e);
        return null;
      } else {
        throw e;
      }
    }
    return result;
  }
}
<|endoftext|>


<commit_before>const root = '../../';
const utils = require('../testing-utils.js');

jest.useFakeTimers();

describe('data conversion to json', function(){

	beforeEach(function(){
		require(root + 'jspsych.js');
  });

  test('survey-text data response object is correctly converted', function(){
    require(root + 'plugins/jspsych-survey-text.js');

    var trial = {
      type: 'survey-text',
      questions: [
        {prompt: 'Q1'},
        {prompt: 'Q2'}
      ]
    }

    var timeline = [trial];

    jsPsych.init({timeline});

    document.querySelector('#input-0').value = 'Response 1';
    document.querySelector('#input-1').value = 'Response 2';

    utils.clickTarget(document.querySelector('#jspsych-survey-text-next'));

    var json_data = jsPsych.data.get().ignore(['rt','internal_node_id', 'time_elapsed', 'trial_type']).json();
    expect(json_data).toBe(JSON.stringify([{responses: {Q0: "Response 1", Q1: "Response 2"}, trial_index: 0}]));
  })

  test('same-different-html stimulus array is correctly converted', function(){
    require(root + 'plugins/jspsych-same-different-html.js');

    var trial = {
      type: 'same-different-html',
      stimuli: ['
Climbing
', '
Walking
'],
      answer: 'different',
      gap_duration: 0,
      first_stim_duration: null
    }

    var timeline = [trial];

    jsPsych.init({timeline: timeline});

    expect(jsPsych.getDisplayElement().innerHTML).toMatch('
Climbing
');
    utils.pressKey('q');
    jest.runAllTimers();
    expect(jsPsych.getDisplayElement().innerHTML).toMatch('
Walking
');
    utils.pressKey('q');
    expect(jsPsych.getDisplayElement().innerHTML).toBe('');

    var json_data = jsPsych.data.get().ignore(['rt','internal_node_id','time_elapsed','trial_type','rt_stim1','key_press_stim1']).json();
    expect(json_data).toBe(JSON.stringify([{answer: 'different', correct: false, stimulus: ['
Climbing
','
Walking
'], key_press: 'q',  trial_index: 0}]));
  })

  test('video-button-response stimulus array is correctly converted', function(){
    require(root + 'plugins/jspsych-video-button-response.js');

    var trial = {
      type: 'video-button-response',
      stimulus: ['vid/video.mp4'],
      choices: ['button']
    }

    var timeline = [trial];

    jsPsych.init({timeline: timeline});

    expect(jsPsych.getDisplayElement().innerHTML).toMatch('video.mp4');
    utils.clickTarget(document.querySelector('#jspsych-video-button-response-button-0'));
    expect(jsPsych.getDisplayElement().innerHTML).toBe('');

    var json_data = jsPsych.data.get().ignore(['rt','internal_node_id','time_elapsed','trial_type']).json();
    expect(json_data).toBe(JSON.stringify([{stimulus: ['vid/video.mp4'], button_pressed: 0, trial_index: 0}]));
  })

  test('survey-multi-select response array is correctly converted', function(){
    require(root + 'plugins/jspsych-survey-multi-select.js');

    var trial = {
      type: 'survey-multi-select',
      questions: [
        {prompt: "foo", options: ["fuzz", "bizz", "bar"], name: 'q'}
      ]
    };

    var timeline = [trial];

    jsPsych.init({timeline: timeline});

    expect(jsPsych.getDisplayElement().innerHTML).toMatch('foo');
    utils.clickTarget(document.querySelector('#jspsych-survey-multi-select-response-0-0'));
    utils.clickTarget(document.querySelector('#jspsych-survey-multi-select-response-0-1'));
    utils.clickTarget(document.querySelector('#jspsych-survey-multi-select-next'));
    expect(jsPsych.getDisplayElement().innerHTML).toBe('');

    var json_data = jsPsych.data.get().ignore(['rt','internal_node_id','time_elapsed','trial_type','question_order']).json();
    var data_js = [
      {
        responses: {
          q: ["fuzz","bizz"],
        },
        trial_index: 0
      }
    ];
    expect(json_data).toBe(JSON.stringify(data_js));
  })

  test('jsPsych json function is the same as JSON.stringify', function(){
    require(root + 'plugins/jspsych-survey-multi-select.js');

    var trial = {
      type: 'survey-multi-select',
      questions: [
        {prompt: "foo", options: ["fuzz", "bizz", "bar"], name: 'q'}
      ]
    };

    var timeline = [trial];

    jsPsych.init({timeline: timeline});

    expect(jsPsych.getDisplayElement().innerHTML).toMatch('foo');
    utils.clickTarget(document.querySelector('#jspsych-survey-multi-select-response-0-0'));
    utils.clickTarget(document.querySelector('#jspsych-survey-multi-select-response-0-1'));
    utils.clickTarget(document.querySelector('#jspsych-survey-multi-select-next'));
    expect(jsPsych.getDisplayElement().innerHTML).toBe('');

    var json_data = jsPsych.data.get().ignore(['rt','internal_node_id','time_elapsed','trial_type','question_order']).json();
    var data_js = [
      {
        responses: {
          q: ["fuzz","bizz"],
        },
        trial_index: 0
      }
    ];
    expect(json_data).toBe(JSON.stringify(data_js));
  })

});<commit_msg>remove redundant test<commit_after>const root = '../../';
const utils = require('../testing-utils.js');

jest.useFakeTimers();

describe('data conversion to json', function(){

	beforeEach(function(){
		require(root + 'jspsych.js');
  });

  test('survey-text data response object is correctly converted', function(){
    require(root + 'plugins/jspsych-survey-text.js');

    var trial = {
      type: 'survey-text',
      questions: [
        {prompt: 'Q1'},
        {prompt: 'Q2'}
      ]
    }

    var timeline = [trial];

    jsPsych.init({timeline});

    document.querySelector('#input-0').value = 'Response 1';
    document.querySelector('#input-1').value = 'Response 2';

    utils.clickTarget(document.querySelector('#jspsych-survey-text-next'));

    var json_data = jsPsych.data.get().ignore(['rt','internal_node_id', 'time_elapsed', 'trial_type']).json();
    expect(json_data).toBe(JSON.stringify([{responses: {Q0: "Response 1", Q1: "Response 2"}, trial_index: 0}]));
  })

  test('same-different-html stimulus array is correctly converted', function(){
    require(root + 'plugins/jspsych-same-different-html.js');

    var trial = {
      type: 'same-different-html',
      stimuli: ['
Climbing
', '
Walking
'],
      answer: 'different',
      gap_duration: 0,
      first_stim_duration: null
    }

    var timeline = [trial];

    jsPsych.init({timeline: timeline});

    expect(jsPsych.getDisplayElement().innerHTML).toMatch('
Climbing
');
    utils.pressKey('q');
    jest.runAllTimers();
    expect(jsPsych.getDisplayElement().innerHTML).toMatch('
Walking
');
    utils.pressKey('q');
    expect(jsPsych.getDisplayElement().innerHTML).toBe('');

    var json_data = jsPsych.data.get().ignore(['rt','internal_node_id','time_elapsed','trial_type','rt_stim1','key_press_stim1']).json();
    expect(json_data).toBe(JSON.stringify([{answer: 'different', correct: false, stimulus: ['
Climbing
','
Walking
'], key_press: 'q',  trial_index: 0}]));
  })

  test('video-button-response stimulus array is correctly converted', function(){
    require(root + 'plugins/jspsych-video-button-response.js');

    var trial = {
      type: 'video-button-response',
      stimulus: ['vid/video.mp4'],
      choices: ['button']
    }

    var timeline = [trial];

    jsPsych.init({timeline: timeline});

    expect(jsPsych.getDisplayElement().innerHTML).toMatch('video.mp4');
    utils.clickTarget(document.querySelector('#jspsych-video-button-response-button-0'));
    expect(jsPsych.getDisplayElement().innerHTML).toBe('');

    var json_data = jsPsych.data.get().ignore(['rt','internal_node_id','time_elapsed','trial_type']).json();
    expect(json_data).toBe(JSON.stringify([{stimulus: ['vid/video.mp4'], button_pressed: 0, trial_index: 0}]));
  })

  test('survey-multi-select response array is correctly converted', function(){
    require(root + 'plugins/jspsych-survey-multi-select.js');

    var trial = {
      type: 'survey-multi-select',
      questions: [
        {prompt: "foo", options: ["fuzz", "bizz", "bar"], name: 'q'}
      ]
    };

    var timeline = [trial];

    jsPsych.init({timeline: timeline});

    expect(jsPsych.getDisplayElement().innerHTML).toMatch('foo');
    utils.clickTarget(document.querySelector('#jspsych-survey-multi-select-response-0-0'));
    utils.clickTarget(document.querySelector('#jspsych-survey-multi-select-response-0-1'));
    utils.clickTarget(document.querySelector('#jspsych-survey-multi-select-next'));
    expect(jsPsych.getDisplayElement().innerHTML).toBe('');

    var json_data = jsPsych.data.get().ignore(['rt','internal_node_id','time_elapsed','trial_type','question_order']).json();
    var data_js = [
      {
        responses: {
          q: ["fuzz","bizz"],
        },
        trial_index: 0
      }
    ];
    expect(json_data).toBe(JSON.stringify(data_js));
  })

});<|endoftext|>


<commit_before>exports.extend = function extend(dest, from) {
    var props = Object.getOwnPropertyNames(from), destination;

    props.forEach(function(name) {
        if (typeof from[name] === 'object') {
            if (typeof dest[name] !== 'object') {
                dest[name] = {}
            }
            extend(dest[name], from[name]);
        } else {
            destination = Object.getOwnPropertyDescriptor(from, name);
            Object.defineProperty(dest, name, destination);
        }
    });

    return dest;
};

exports.buildCommandParameters = function(options) {
    var params = [];

    for (key in options) {
        var val = options[key];

        if (val !== undefined) {
            if (typeof val == 'boolean') {
                val && params.push('--' + key);
            } else {
                params.push('--' + key);
                params.push(val)
            }
        }
    }
    return params;
};
<commit_msg>verbose parameter should always has value<commit_after>exports.extend = function extend(dest, from) {
    var props = Object.getOwnPropertyNames(from), destination;

    props.forEach(function(name) {
        if (typeof from[name] === 'object') {
            if (typeof dest[name] !== 'object') {
                dest[name] = {}
            }
            extend(dest[name], from[name]);
        } else {
            destination = Object.getOwnPropertyDescriptor(from, name);
            Object.defineProperty(dest, name, destination);
        }
    });

    return dest;
};

exports.buildCommandParameters = function(options) {
    var params = [];

    for (key in options) {
        var val = options[key];

        if (val !== undefined) {
            if (typeof val == 'boolean') {
                val && params.push('--' + key);
                if (val && key == 'verbose')
                    params.push('true')
            } else {
                params.push('--' + key);
                params.push(val)
            }
        }
    }
    return params;
};
<|endoftext|>


<commit_before>'use strict';

const assert = require('assert');
const url = require('url');

const Chrome = require('../');

describe('connecting to Chrome', () => {
    describe('with callback', () => {
        describe('with default parameters', () => {
            it('should succeed with "connect" callback passed as an argument', (done) => {
                Chrome((chrome) => {
                    chrome.close(done);
                }).on('error', () => {
                    assert(false);
                });
            });
        });
        describe('with custom parameters', () => {
            it('should succeed with "connect" callback passed as an argument', (done) => {
                Chrome({'host': 'localhost', 'port': 9222}, (chrome) => {
                    chrome.close(done);
                }).on('error', () => {
                    assert(false);
                });
            });
            it('should succeed with custom target by index', (done) => {
                Chrome({'target': function () { return 0; }}, (chrome) => {
                    chrome.close(done);
                }).on('error', () => {
                    assert(false);
                });
            });
            it('should succeed with custom target by object', (done) => {
                Chrome({'target': function (targets) { return targets[0]; }}, (chrome) => {
                    chrome.close(done);
                }).on('error', () => {
                    assert(false);
                });
            });
            it('should succeed with custom target by full URL', (done) => {
                Chrome.Version((err, info) => {
                    assert.ifError(err);
                    const browserUrl = info.webSocketDebuggerUrl || 'ws://localhost:9222/devtools/browser';
                    Chrome({'target': browserUrl}, (chrome) => {
                        chrome.close(done);
                    }).on('error', () => {
                        assert(false);
                    });
                });
            });
            it('should succeed with custom target by partial URL', (done) => {
                Chrome.Version((err, info) => {
                    assert.ifError(err);
                    if (info.webSocketDebuggerUrl) {
                        info.webSocketDebuggerUrl = url.parse(info.webSocketDebuggerUrl).pathname;
                    }
                    const browserUrl = info.webSocketDebuggerUrl || '/devtools/browser';
                    Chrome({'target': browserUrl}, (chrome) => {
                        chrome.close(done);
                    }).on('error', () => {
                        assert(false);
                    });
                });
            });
            it('should succeed with custom target by id', (done) => {
                Chrome.List((err, targets) => {
                    assert.ifError(err);
                    Chrome({'target': targets[0].id}, (chrome) => {
                        chrome.close(done);
                    }).on('error', () => {
                        assert(false);
                    });
                });
            });
        });
        describe('with custom (wrong) parameters', () => {
            it('should fail (wrong port)', (done) => {
                Chrome({'port': 1}, () => {
                    assert(false);
                }).on('error', (err) => {
                    assert(err instanceof Error);
                    done();
                });
            });
            it('should fail (wrong host)', (done) => {
                Chrome({'host': '255.255.255.255'}, () => {
                    assert(false);
                }).on('error', (err) => {
                    assert(err instanceof Error);
                    done();
                });
            });
            it('should fail (wrong target)', (done) => {
                Chrome({'target': function () { return -1; }}, () => {
                    assert(false);
                }).on('error', (err) => {
                    assert(err instanceof Error);
                    done();
                });
            });
        });
    });
    describe('without callback', () => {
        describe('with default parameters', () => {
            it('should succeed', (done) => {
                Chrome().then((chrome) => {
                    chrome.close(done);
                }).catch(() => {
                    assert(false);
                });
            });
        });
        describe('with custom parameters', () => {
            it('should succeed', (done) => {
                Chrome({'host': 'localhost', 'port': 9222}).then((chrome) => {
                    chrome.close(done);
                }).catch(() => {
                    assert(false);
                });
            });
            it('should succeed with custom target by index', (done) => {
                Chrome({'target': function () { return 0; }}).then((chrome) => {
                    chrome.close(done);
                }).catch(() => {
                    assert(false);
                });
            });
            it('should succeed with custom target by index', (done) => {
                Chrome({'target': function (targets) { return targets[0]; }}).then((chrome) => {
                    chrome.close(done);
                }).catch(() => {
                    assert(false);
                });
            });
            it('should succeed with custom target by full URL', (done) => {
                Chrome.Version((err, info) => {
                    assert.ifError(err);
                    const browserUrl = info.webSocketDebuggerUrl || 'ws://localhost:9222/devtools/browser';
                    Chrome({'target': browserUrl}).then((chrome) => {
                        chrome.close(done);
                    }).catch(() => {
                        assert(false);
                    });
                });
            });
            it('should succeed with custom target by partial URL', (done) => {
                Chrome.Version((err, info) => {
                    assert.ifError(err);
                    if (info.webSocketDebuggerUrl) {
                        info.webSocketDebuggerUrl = url.parse(info.webSocketDebuggerUrl).pathname;
                    }
                    const browserUrl = info.webSocketDebuggerUrl || '/devtools/browser';
                    Chrome({'target': browserUrl}).then((chrome) => {
                        chrome.close(done);
                    }).catch(() => {
                        assert(false);
                    });
                });
            });
            it('should succeed with custom target by id', (done) => {
                Chrome.List((err, targets) => {
                    assert.ifError(err);
                    Chrome({'target': targets[0].id}).then((chrome) => {
                        chrome.close(done);
                    }).catch(() => {
                        assert(false);
                    });
                });
            });
        });
        describe('with custom (wrong) parameters', () => {
            it('should fail (wrong port)', (done) => {
                Chrome({'port': 1}).then(() => {
                    done(new Error());
                }).catch((err) => {
                    assert(err instanceof Error);
                    done();
                });
            });
            it('should fail (wrong host)', (done) => {
                Chrome({'host': '255.255.255.255'}).then(() => {
                    done(new Error());
                }).catch((err) => {
                    assert(err instanceof Error);
                    done();
                });
            });
            it('should fail (wrong target)', (done) => {
                Chrome({'target': function () { return -1; }}).then(() => {
                    done(new Error());
                }).catch((err) => {
                    assert(err instanceof Error);
                    done();
                });
            });
        });
    });
});
<commit_msg>Add missing connection test case<commit_after>'use strict';

const assert = require('assert');
const url = require('url');

const Chrome = require('../');

describe('connecting to Chrome', () => {
    describe('with callback', () => {
        describe('with default parameters', () => {
            it('should succeed with "connect" callback passed as an argument', (done) => {
                Chrome((chrome) => {
                    chrome.close(done);
                }).on('error', () => {
                    assert(false);
                });
            });
        });
        describe('with custom parameters', () => {
            it('should succeed with "connect" callback passed as an argument', (done) => {
                Chrome({'host': 'localhost', 'port': 9222}, (chrome) => {
                    chrome.close(done);
                }).on('error', () => {
                    assert(false);
                });
            });
            it('should succeed with custom target by index', (done) => {
                Chrome({'target': function () { return 0; }}, (chrome) => {
                    chrome.close(done);
                }).on('error', () => {
                    assert(false);
                });
            });
            it('should succeed with custom target by function', (done) => {
                Chrome({'target': function (targets) { return targets[0]; }}, (chrome) => {
                    chrome.close(done);
                }).on('error', () => {
                    assert(false);
                });
            });
            it('should succeed with custom target by object', (done) => {
                Chrome.Version((err, info) => {
                    assert.ifError(err);
                    Chrome({'target': info}, (chrome) => {
                        chrome.close(done);
                    }).on('error', () => {
                        assert(false);
                    });
                });
            });
            it('should succeed with custom target by full URL', (done) => {
                Chrome.Version((err, info) => {
                    assert.ifError(err);
                    const browserUrl = info.webSocketDebuggerUrl || 'ws://localhost:9222/devtools/browser';
                    Chrome({'target': browserUrl}, (chrome) => {
                        chrome.close(done);
                    }).on('error', () => {
                        assert(false);
                    });
                });
            });
            it('should succeed with custom target by partial URL', (done) => {
                Chrome.Version((err, info) => {
                    assert.ifError(err);
                    if (info.webSocketDebuggerUrl) {
                        info.webSocketDebuggerUrl = url.parse(info.webSocketDebuggerUrl).pathname;
                    }
                    const browserUrl = info.webSocketDebuggerUrl || '/devtools/browser';
                    Chrome({'target': browserUrl}, (chrome) => {
                        chrome.close(done);
                    }).on('error', () => {
                        assert(false);
                    });
                });
            });
            it('should succeed with custom target by id', (done) => {
                Chrome.List((err, targets) => {
                    assert.ifError(err);
                    Chrome({'target': targets[0].id}, (chrome) => {
                        chrome.close(done);
                    }).on('error', () => {
                        assert(false);
                    });
                });
            });
        });
        describe('with custom (wrong) parameters', () => {
            it('should fail (wrong port)', (done) => {
                Chrome({'port': 1}, () => {
                    assert(false);
                }).on('error', (err) => {
                    assert(err instanceof Error);
                    done();
                });
            });
            it('should fail (wrong host)', (done) => {
                Chrome({'host': '255.255.255.255'}, () => {
                    assert(false);
                }).on('error', (err) => {
                    assert(err instanceof Error);
                    done();
                });
            });
            it('should fail (wrong target)', (done) => {
                Chrome({'target': function () { return -1; }}, () => {
                    assert(false);
                }).on('error', (err) => {
                    assert(err instanceof Error);
                    done();
                });
            });
        });
    });
    describe('without callback', () => {
        describe('with default parameters', () => {
            it('should succeed', (done) => {
                Chrome().then((chrome) => {
                    chrome.close(done);
                }).catch(() => {
                    assert(false);
                });
            });
        });
        describe('with custom parameters', () => {
            it('should succeed', (done) => {
                Chrome({'host': 'localhost', 'port': 9222}).then((chrome) => {
                    chrome.close(done);
                }).catch(() => {
                    assert(false);
                });
            });
            it('should succeed with custom target by index', (done) => {
                Chrome({'target': function () { return 0; }}).then((chrome) => {
                    chrome.close(done);
                }).catch(() => {
                    assert(false);
                });
            });
            it('should succeed with custom target by index', (done) => {
                Chrome({'target': function (targets) { return targets[0]; }}).then((chrome) => {
                    chrome.close(done);
                }).catch(() => {
                    assert(false);
                });
            });
            it('should succeed with custom target by full URL', (done) => {
                Chrome.Version((err, info) => {
                    assert.ifError(err);
                    const browserUrl = info.webSocketDebuggerUrl || 'ws://localhost:9222/devtools/browser';
                    Chrome({'target': browserUrl}).then((chrome) => {
                        chrome.close(done);
                    }).catch(() => {
                        assert(false);
                    });
                });
            });
            it('should succeed with custom target by partial URL', (done) => {
                Chrome.Version((err, info) => {
                    assert.ifError(err);
                    if (info.webSocketDebuggerUrl) {
                        info.webSocketDebuggerUrl = url.parse(info.webSocketDebuggerUrl).pathname;
                    }
                    const browserUrl = info.webSocketDebuggerUrl || '/devtools/browser';
                    Chrome({'target': browserUrl}).then((chrome) => {
                        chrome.close(done);
                    }).catch(() => {
                        assert(false);
                    });
                });
            });
            it('should succeed with custom target by id', (done) => {
                Chrome.List((err, targets) => {
                    assert.ifError(err);
                    Chrome({'target': targets[0].id}).then((chrome) => {
                        chrome.close(done);
                    }).catch(() => {
                        assert(false);
                    });
                });
            });
        });
        describe('with custom (wrong) parameters', () => {
            it('should fail (wrong port)', (done) => {
                Chrome({'port': 1}).then(() => {
                    done(new Error());
                }).catch((err) => {
                    assert(err instanceof Error);
                    done();
                });
            });
            it('should fail (wrong host)', (done) => {
                Chrome({'host': '255.255.255.255'}).then(() => {
                    done(new Error());
                }).catch((err) => {
                    assert(err instanceof Error);
                    done();
                });
            });
            it('should fail (wrong target)', (done) => {
                Chrome({'target': function () { return -1; }}).then(() => {
                    done(new Error());
                }).catch((err) => {
                    assert(err instanceof Error);
                    done();
                });
            });
        });
    });
});
<|endoftext|>


<commit_before>var utils = require('./utils.js');

describe('admin add, configure and delete questionnaires', function() {
  var add_questionnaires = function(questionnaire_name) {
    var add_button = element(by.css('[data-ng-click="add_questionnaire()"]'));
    element(by.model('new_questionnaire.name')).sendKeys(questionnaire_name);
    browser.actions().mouseMove(add_button).click().perform();
    utils.waitUntilReady(element(by.xpath(".//*[text()='" + questionnaire_name + "']")));
  };

  var add_question = function(question_type) {
    var add_button = element.all(by.css('[data-ng-click="add_field()"]')).first();
    element.all(by.model('new_field.label')).first().sendKeys(question_type);
    element.all(by.model('new_field.type')).first().element(by.xpath(".//*[text()='" + question_type + "']")).click();
    browser.actions().mouseMove(add_button).click().perform();
  };

  var add_step = function(step_label) {
    var add_button = element(by.css('[data-ng-click="add_step()"]'));
    element(by.model('new_step.label')).sendKeys(step_label);
    browser.actions().mouseMove(add_button).click().perform();
    utils.waitUntilReady(element(by.xpath(".//*[text()='" + step_label + "']")));
  };

  it('should add new questionnaires', function() {
    browser.setLocation('admin/questionnaires');

    utils.waitUntilReady(element(by.xpath(".//*[text()='Default']")));

    add_questionnaires('Questionnaire 1');
    add_questionnaires('Questionnaire 2');
  });

  it('should configure steps and questions', function() {
    // Open Questionnaire 1
    element(by.xpath(".//*[text()='Questionnaire 1']")).click();

    add_step("Step 1");
    add_step("Step 2");

    // Open Step 1
    element(by.xpath(".//*[text()='Step 1']")).click();

    for(var i=0; i<utils.vars.field_types.length; i++){
      add_question(utils.vars.field_types[i]);
    }

    // Close Step 1
    element(by.xpath(".//*[text()='Step 1']")).click();

    // Close Questionnaire 1
    element(by.xpath(".//*[text()='Questionnaire 1']")).click();
  });

  it('should del existing questionnaires', function() {
    element.all(by.css('.actionButtonDelete')).last().click();
  });

  it('should add new question templates', function() {
    element(by.cssContainingText("a", "Question templates")).click();

    element(by.cssContainingText("span", "Do you want to provide your identification information?")).click();

    for(var i=0; i<utils.vars.field_types.length; i++){
      add_question(utils.vars.field_types[i]);
    }
  });
});
<commit_msg>Revert "Trial and error on solving TravisCi/Firefox/Randomness issues"<commit_after>var utils = require('./utils.js');

describe('admin add, configure and delete questionnaires', function() {
  var add_questionnaires = function(questionnaire_name) {
    element(by.model('new_questionnaire.name')).sendKeys(questionnaire_name);
    element(by.css('[data-ng-click="add_questionnaire()"]')).click();
    utils.waitUntilReady(element(by.xpath(".//*[text()='" + questionnaire_name + "']")));
  };

  var add_question = function(question_type) {
    element.all(by.model('new_field.label')).first().sendKeys(question_type);
    element.all(by.model('new_field.type')).first().element(by.xpath(".//*[text()='" + question_type + "']")).click();
    element.all(by.css('[data-ng-click="add_field()"]')).first().click();
  };

  var add_step = function(step_label) {
    element(by.model('new_step.label')).sendKeys(step_label);
    element(by.css('[data-ng-click="add_step()"]')).click();
    utils.waitUntilReady(element(by.xpath(".//*[text()='" + step_label + "']")));
  };

  it('should add new questionnaires', function() {
    browser.setLocation('admin/questionnaires');

    utils.waitUntilReady(element(by.xpath(".//*[text()='Default']")));

    add_questionnaires('Questionnaire 1');
    add_questionnaires('Questionnaire 2');
  });

  it('should configure steps and questions', function() {
    // Open Questionnaire 1
    element(by.xpath(".//*[text()='Questionnaire 1']")).click();

    add_step("Step 1");
    add_step("Step 2");

    // Open Step 1
    element(by.xpath(".//*[text()='Step 1']")).click();

    for(var i=0; i<utils.vars.field_types.length; i++){
      add_question(utils.vars.field_types[i]);
    }

    // Close Step 1
    element(by.xpath(".//*[text()='Step 1']")).click();

    // Close Questionnaire 1
    element(by.xpath(".//*[text()='Questionnaire 1']")).click();
  });

  it('should del existing questionnaires', function() {
    element.all(by.css('.actionButtonDelete')).last().click();
  });

  it('should add new question templates', function() {
    element(by.cssContainingText("a", "Question templates")).click();

    element(by.cssContainingText("span", "Do you want to provide your identification information?")).click();

    for(var i=0; i<utils.vars.field_types.length; i++){
      add_question(utils.vars.field_types[i]);
    }
  });
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
// Downloads various README files from GitHub.

const async = require("async");
const fetch = require("node-fetch");
const fs = require("fs");

const CONCURRENT_REQUESTS = 20;

const addFrontMatter = (id, text) =>
  `---
id: ${id}
title: ${id}
sidebar_label: ${id.replace(/^babel-(plugin|proposal|preset)-/, "")}
---

[comment]: # Don't edit this file directly, it was copied using scripts/download-readmes.js

${text}
`;

function getDirectoryListing(repo, branch = "master") {
  let url = `https://api.github.com/repos/babel/${repo}/contents/packages?ref=${branch}`;
  if (process.env.GITHUB_CLIENT_ID && process.env.GITHUB_CLIENT_SECRET) {
    // This is intentionally using client_id and client_secret rather than an access_token
    // so that accidental exposure of the access token does not expose API access.
    // Passing client_id and client_secret *without* an access token is sufficient to hit the
    // increased rate limits.
    url += `&client_id=${encodeURIComponent(process.env.GITHUB_CLIENT_ID)}`;
    url += `&client_secret=${encodeURIComponent(
      process.env.GITHUB_CLIENT_SECRET
    )}`;
  }

  return fetch(url)
    .then(res => res.json())
    .then(packages => ({ branch, packages, repo }));
}

function getReadmeURLsFromDirectoryListing({ branch, packages, repo }) {
  return packages.filter(file => file.type === "dir").map(file => ({
    name: file.name,
    uri: `/babel/${repo}/${branch}/${file.path}/README.md`
  }));
}

console.log("Retrieving package listing...");
Promise.all([
  getDirectoryListing("babel", "master"),
  getDirectoryListing("minify")
])
  .then(([babelPackages, babiliPackages]) => {
    const packages = [
      ...getReadmeURLsFromDirectoryListing(babelPackages),
      ...getReadmeURLsFromDirectoryListing(babiliPackages),
    ];

    const plugins = [];
    const presets = [];
    const prefixes = ["preset", "plugin", "proposal"];

    console.log("Downloading READMEs...");

    async.mapLimit(packages, CONCURRENT_REQUESTS, (package, cb) => {
      fetch(`https://raw.githubusercontent.com${package.uri}`)
        .then(res => res.text())
        .then(
          text => {
            const filename = package.name.replace(/^babel-/, "");

            // This is extremely hacky/temporary, and simply mimics what we
            // were doing in the old jekyll setup in
            // _includes/package_readme.html. It only works because the READMEs
            // are generally standardized to start with:
            //
            // # babel-something
            //
            // > Some description
            //
            let parsedText = text
              .split("\n")
              .slice(4)
              .join("\n");

            // Adds the necessary frontmatter info for docusaurus
            parsedText = addFrontMatter(package.name, parsedText);

            fs.writeFile(
              `${__dirname}/../docs/${filename}.md`,
              parsedText,
              cb
            );
          },
          err => {
            console.error(`Could not load ${package.name}: ${err}`);
          }
        );
    });
  })
  .catch(err => {
    console.error(`Could not retrieve package listing: ${err}`);
    process.exit(1);
  });
<commit_msg>Hide markdown comment from pages (#1640)<commit_after>#!/usr/bin/env node
// Downloads various README files from GitHub.

const async = require("async");
const fetch = require("node-fetch");
const fs = require("fs");

const CONCURRENT_REQUESTS = 20;

const addFrontMatter = (id, text) =>
  `---
id: ${id}
title: ${id}
sidebar_label: ${id.replace(/^babel-(plugin|proposal|preset)-/, "")}
---

[comment]: # (Don't edit this file directly, it was copied using scripts/download-readmes.js)

${text}
`;

function getDirectoryListing(repo, branch = "master") {
  let url = `https://api.github.com/repos/babel/${repo}/contents/packages?ref=${branch}`;
  if (process.env.GITHUB_CLIENT_ID && process.env.GITHUB_CLIENT_SECRET) {
    // This is intentionally using client_id and client_secret rather than an access_token
    // so that accidental exposure of the access token does not expose API access.
    // Passing client_id and client_secret *without* an access token is sufficient to hit the
    // increased rate limits.
    url += `&client_id=${encodeURIComponent(process.env.GITHUB_CLIENT_ID)}`;
    url += `&client_secret=${encodeURIComponent(
      process.env.GITHUB_CLIENT_SECRET
    )}`;
  }

  return fetch(url)
    .then(res => res.json())
    .then(packages => ({ branch, packages, repo }));
}

function getReadmeURLsFromDirectoryListing({ branch, packages, repo }) {
  return packages.filter(file => file.type === "dir").map(file => ({
    name: file.name,
    uri: `/babel/${repo}/${branch}/${file.path}/README.md`
  }));
}

console.log("Retrieving package listing...");
Promise.all([
  getDirectoryListing("babel", "master"),
  getDirectoryListing("minify")
])
  .then(([babelPackages, babiliPackages]) => {
    const packages = [
      ...getReadmeURLsFromDirectoryListing(babelPackages),
      ...getReadmeURLsFromDirectoryListing(babiliPackages),
    ];

    const plugins = [];
    const presets = [];
    const prefixes = ["preset", "plugin", "proposal"];

    console.log("Downloading READMEs...");

    async.mapLimit(packages, CONCURRENT_REQUESTS, (package, cb) => {
      fetch(`https://raw.githubusercontent.com${package.uri}`)
        .then(res => res.text())
        .then(
          text => {
            const filename = package.name.replace(/^babel-/, "");

            // This is extremely hacky/temporary, and simply mimics what we
            // were doing in the old jekyll setup in
            // _includes/package_readme.html. It only works because the READMEs
            // are generally standardized to start with:
            //
            // # babel-something
            //
            // > Some description
            //
            let parsedText = text
              .split("\n")
              .slice(4)
              .join("\n");

            // Adds the necessary frontmatter info for docusaurus
            parsedText = addFrontMatter(package.name, parsedText);

            fs.writeFile(
              `${__dirname}/../docs/${filename}.md`,
              parsedText,
              cb
            );
          },
          err => {
            console.error(`Could not load ${package.name}: ${err}`);
          }
        );
    });
  })
  .catch(err => {
    console.error(`Could not retrieve package listing: ${err}`);
    process.exit(1);
  });
<|endoftext|>


<commit_before>// sets up a folder for omnisharp to run off of, using the same dependencies
// as the query program. uses platform appropiate persisted user storage
const fs = require('fs');
const path = require('path');
const unzip = require('unzip');

const userStore = process.platform !== 'win32' ?
    `${process.env.HOME}/.ream-editor/` :
    `${process.env.LOCALAPPDATA}\\ReamEditor\\`;

const dstPath = path.resolve(`${userStore}/dist`);
const zipPath = path.resolve(`${__dirname}/reamquery.zip`);

console.log('omnisharp-setup zipPath: ', zipPath)
console.log('omnisharp-setup dstPath: ', dstPath)

// todo error handling and all that
rmdir(dstPath, () => {
    fs.createReadStream(zipPath)
        .pipe(unzip.Extract({ path: dstPath }));
});

// https://gist.github.com/tkihira/2367067
function rmdir(dir, cb) {
	var list = fs.readdirSync(dir);
	for(var i = 0; i < list.length; i++) {
		var filename = path.join(dir, list[i]);
		var stat = fs.statSync(filename);

		if(filename == "." || filename == "..") {
			// pass these files
		} else if(stat.isDirectory()) {
			// rmdir recursively
			rmdir(filename);
		} else {
			// rm fiilename
			fs.unlinkSync(filename);
		}
	}
	fs.rmdirSync(dir);
    if (cb) {
        cb();
    }
}
<commit_msg>Prevent err when dir doesnt exist<commit_after>// sets up a folder for omnisharp to run off of, using the same dependencies
// as the query program. uses platform appropiate persisted user storage
const fs = require('fs');
const path = require('path');
const unzip = require('unzip');

const userStore = process.platform !== 'win32' ?
    `${process.env.HOME}/.ream-editor/` :
    `${process.env.LOCALAPPDATA}\\ReamEditor\\`;

const dstPath = path.resolve(`${userStore}/dist`);
const zipPath = path.resolve(`${__dirname}/reamquery.zip`);

console.log('omnisharp-setup zipPath: ', zipPath)
console.log('omnisharp-setup dstPath: ', dstPath)

// todo error handling and all that
rmdir(dstPath, () => {
    fs.createReadStream(zipPath)
        .pipe(unzip.Extract({ path: dstPath }));
});

// https://gist.github.com/tkihira/2367067
function rmdir(dir, cb) {
	if (fs.existsSync(dir)) {
		var list = fs.readdirSync(dir);
		for(var i = 0; i < list.length; i++) {
			var filename = path.join(dir, list[i]);
			var stat = fs.statSync(filename);

			if(filename == "." || filename == "..") {
				// pass these files
			} else if(stat.isDirectory()) {
				// rmdir recursively
				rmdir(filename);
			} else {
				// rm fiilename
				fs.unlinkSync(filename);
			}
		}
		fs.rmdirSync(dir);
	}
    if (cb) {
        cb();
    }
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import firebase, { reference, signIn } from '../firebase';
import { pick, map, extend } from 'lodash';
import SubmitMessage from './submit-message.js';
import ClearInput from './clear-input.js';
import LogInButton from './login-button.js';
import LogOutButton from './logout-button.js';
import moment from 'moment';

export default class Application extends Component {
  constructor() {
    super();
    this.state = {
      messages: [],
      newMessage: '',
      user: ''
    };

  } //end of constructor

  componentDidMount(){
  //
  } //end of componentDidMount

  handleInputChange(e){
    this.setState({newMessage: e.target.value});
    let submitButton = document.querySelector('.submit-message-button');
    let clearButton = document.querySelector('.clear-message-button');
    if (this.state.newMessage !== '') {
      submitButton.removeAttribute('disabled');
      clearButton.removeAttribute('disabled');
    }

  } //end of handleInputChange

  initFirebase(){ //needs to be called on page load
    this.auth = firebase.auth();
    this.database = firebase.database();
    this.auth.onAuthStateChanged(this.onAuthStateChanged.bind(this));
  } // end of initFirebase

  loadMessages(){
    let that = this;
    reference.limitToLast(50).on('value', function (snapshot) {
      var messagesReturned = that.returnArray(snapshot.val());
      that.setState({messages: messagesReturned});
    }); //end of snapshot function
  } //end of loadMessages

  returnArray(snapshots){
    let array = [];
    if (snapshots) {
      var fullArray = Object.keys(snapshots).map((each)=>{
        var singleMessage = snapshots[each];
        singleMessage['each'] = each;
        array.push(singleMessage);
      });
    }
    return array;
  } //end of returnArray

  onAuthStateChanged(user){
    if (user) {
      let profilePicUrl = user.photoURL;
      let userName = user.displayName;
      let userNameField = document.getElementById('user-name');
      let userPicField = document.getElementById('user-pic');
      let logInButton = document.querySelector('.login-button');
      let logOutButton = document.querySelector('.logout-button');
      userNameField.textContent = userName;
      userPicField.setAttribute('src', profilePicUrl);
      userNameField.removeAttribute('hidden');
      userPicField.removeAttribute('hidden');
      logOutButton.removeAttribute('hidden');
      logInButton.setAttribute('hidden', 'true');
      // this.loadMessages();
    } //end of if user is signed in
    else {
      let userNameField = document.getElementById('user-name');
      let userPicField = document.getElementById('user-pic');
      let signOutButton = document.querySelector('.logout-button');
      userNameField.setAttribute('hidden', 'true');
      userPicField.setAttribute('hidden', 'true');
      signOutButton.setAttribute('hidden', 'true');
      //show the log in button of needed

    } //end of else user is signed out
  } //end of onAuthStateChanged

  isUserSignedIn(){
    if (this.auth.currentUser) {
    return true;
    }
  } //end of isUserSignedIn

  saveMessage(){
    // event.preventDefault();
    // let that = this;
    if (this.state.newMessage !== '' && this.isUserSignedIn()) {
      //user is signed in
      let currentUser = this.auth.currentUser;
      let body = this.state.newMessage;
      this.state.messages.push(body);
      reference.push({
        user: currentUser.displayName,
        body: body,
        photo: currentUser.photoURL,
        time: moment().toString()
      });
      this.setState({newMessage: ''});
      this.loadMessages();
    } //end of if statement
  } //end of saveMessage

  signIn(){
    let provider = new firebase.auth.GoogleAuthProvider();
    this.auth.signInWithPopup(provider);
  } //end of signIn

  signOut(){
    this.auth.signOut();
  }

  render(){
    return (

        <LogInButton handleClick={()=>this.signIn()}/>
        <LogOutButton handleClick={()=>this.signOut()}/>
        <input id="message-entry-field" type="text" placeholder="Message" onChange={this.handleInputChange.bind(this)} value={this.state.newMessage}></input>

Count

        <SubmitMessage handleClick={()=>this.saveMessage()}/>
        <ClearInput  />
        <ChatMaster user={this.state.user} messages={this.state.messages}/>

    )
  }

} //end of Application

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

  } //end of constructor

  showMessages(messages){ //the card for each message
    return(

On {messages.time}, {messages.user} says:

{messages.body}

    )
  }

  render () {
    return (

{this.props.messages.map(this.showMessages)}

 //end of main div
    );
  }
} //end of ChatMaster

module.exports = Application;
<commit_msg>mssgs now limited to last 25<commit_after>import React, { Component } from 'react';
import firebase, { reference, signIn } from '../firebase';
import { pick, map, extend } from 'lodash';
import SubmitMessage from './submit-message.js';
import ClearInput from './clear-input.js';
import LogInButton from './login-button.js';
import LogOutButton from './logout-button.js';
import moment from 'moment';

export default class Application extends Component {
  constructor() {
    super();
    this.state = {
      messages: [],
      newMessage: '',
      user: ''
    };

  } //end of constructor

  componentDidMount(){
  //
  } //end of componentDidMount

  handleInputChange(e){
    this.setState({newMessage: e.target.value});
    let submitButton = document.querySelector('.submit-message-button');
    let clearButton = document.querySelector('.clear-message-button');
    if (this.state.newMessage !== '') {
      submitButton.removeAttribute('disabled');
      clearButton.removeAttribute('disabled');
    }

  } //end of handleInputChange

  initFirebase(){ //needs to be called on page load
    this.auth = firebase.auth();
    this.database = firebase.database();
    this.auth.onAuthStateChanged(this.onAuthStateChanged.bind(this));
  } // end of initFirebase

  loadMessages(){
    let that = this;
    reference.limitToLast(25).on('value', function (snapshot) {
      var messagesReturned = that.returnArray(snapshot.val());
      that.setState({messages: messagesReturned});
    }); //end of snapshot function
  } //end of loadMessages

  returnArray(snapshots){
    let array = [];
    if (snapshots) {
      var fullArray = Object.keys(snapshots).map((each)=>{
        var singleMessage = snapshots[each];
        singleMessage['each'] = each;
        array.push(singleMessage);
      });
    }
    return array;
  } //end of returnArray

  onAuthStateChanged(user){
    if (user) {
      let profilePicUrl = user.photoURL;
      let userName = user.displayName;
      let userNameField = document.getElementById('user-name');
      let userPicField = document.getElementById('user-pic');
      let logInButton = document.querySelector('.login-button');
      let logOutButton = document.querySelector('.logout-button');
      userNameField.textContent = userName;
      userPicField.setAttribute('src', profilePicUrl);
      userNameField.removeAttribute('hidden');
      userPicField.removeAttribute('hidden');
      logOutButton.removeAttribute('hidden');
      logInButton.setAttribute('hidden', 'true');
      // this.loadMessages();
    } //end of if user is signed in
    else {
      let userNameField = document.getElementById('user-name');
      let userPicField = document.getElementById('user-pic');
      let signOutButton = document.querySelector('.logout-button');
      userNameField.setAttribute('hidden', 'true');
      userPicField.setAttribute('hidden', 'true');
      signOutButton.setAttribute('hidden', 'true');
      //show the log in button of needed

    } //end of else user is signed out
  } //end of onAuthStateChanged

  isUserSignedIn(){
    if (this.auth.currentUser) {
    return true;
    }
  } //end of isUserSignedIn

  saveMessage(){
    // event.preventDefault();
    // let that = this;
    if (this.state.newMessage !== '' && this.isUserSignedIn()) {
      //user is signed in
      let currentUser = this.auth.currentUser;
      let body = this.state.newMessage;
      this.state.messages.push(body);
      reference.push({
        user: currentUser.displayName,
        body: body,
        photo: currentUser.photoURL,
        time: moment().toString()
      });
      this.setState({newMessage: ''});
      this.loadMessages();
    } //end of if statement
  } //end of saveMessage

  signIn(){
    let provider = new firebase.auth.GoogleAuthProvider();
    this.auth.signInWithPopup(provider);
  } //end of signIn

  signOut(){
    this.auth.signOut();
  }

  render(){
    return (

        <LogInButton handleClick={()=>this.signIn()}/>
        <LogOutButton handleClick={()=>this.signOut()}/>
        <input id="message-entry-field" type="text" placeholder="Message" onChange={this.handleInputChange.bind(this)} value={this.state.newMessage}></input>

Count

        <SubmitMessage handleClick={()=>this.saveMessage()}/>
        <ClearInput  />
        <ChatMaster user={this.state.user} messages={this.state.messages}/>

    )
  }

} //end of Application

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

  } //end of constructor

  showMessages(messages){ //the card for each message
    return(

On {messages.time}, {messages.user} says:

{messages.body}

    )
  }

  render () {
    return (

{this.props.messages.map(this.showMessages)}

 //end of main div
    );
  }
} //end of ChatMaster

module.exports = Application;
<|endoftext|>


<commit_before>'use strict'

/**
 * Module dependencies
 */

var utils = require('lazy-cache')(require)

/**
 * Temporarily re-assign `require` to trick browserify and
 * webpack into reconizing lazy dependencies.
 *
 * This tiny bit of ugliness has the huge dual advantage of
 * only loading modules that are actually called at some
 * point in the lifecycle of the application, whilst also
 * allowing browserify and webpack to find modules that
 * are depended on but never actually called.
 */

var fn = require
require = utils // eslint-disable-line no-undef, no-native-reassign, no-global-assign

/**
 * Lazily required module dependencies
 */

require('extend-shallow', 'extend')
require('formidable')
require('koa-body-parsers', 'bodyParsers')
require('querystring')

/**
 * Restore `require`
 */

require = fn // eslint-disable-line no-undef, no-native-reassign, no-global-assign

/**
 * > Patch querystring logic. By default uses node's
 * built-in `querystring` module, otherwise that is
 * provided from `opts.querystring`. Works well with
 * the `qs` module. You can pass it like that
 *
 * **Example**
 *
 * ```js
 * app.use(body({
 *   querystring: require('qs')
 * }))
 * ```
 *
 * @param  {String} `str` querystring
 * @param  {Object} `opts` loaded options
 * @return {Object} parsed querystring object
 * @api private
 */
utils.parseQs = function parseQs (str, opts) {
  opts = utils.extend({
    delimiter: '&',
    decodeURIComponent: utils.querystring.unescape,
    maxKeys: 1000
  }, opts)
  var sep = opts.delimiter || opts.sep

  return opts.querystring
    ? opts.querystring.parse(str, opts)
    : utils.querystring.parse(str, sep, '=', opts)
}

/**
 * > Default options that will be loaded. Pass `options` to overwrite them.
 *
 * @param  {Object} `options`
 * @return {Object}
 * @api private
 */
utils.defaultOptions = function defaultOptions (options) {
  options = typeof options === 'object' ? options : {}
  var types = utils.defaultTypes(options.extendTypes)
  options = utils.extend({
    fields: false,
    files: false,
    multipart: true,
    textLimit: false,
    formLimit: false,
    jsonLimit: false,
    jsonStrict: true,
    detectJSON: false,
    bufferLimit: false,
    buffer: false,
    strict: true
  }, options)
  options.formLimit = options.formLimit || options.urlencodedLimit
  options.extendTypes = types
  options.onerror = options.onЕrror || options.onerror
  options.onerror = typeof options.onerror === 'function' ? options.onerror : false

  if (typeof options.handler !== 'function') {
    options.handler = function * noopHandler () {}
  }
  if (typeof options.detectJSON !== 'function') {
    options.detectJSON = function detectJSON () {
      return false
    }
  }

  return options
}

/**
 * > Only extend/overwrite default accept types.
 *
 * @param  {Object} `types`
 * @return {Object}
 * @api private
 */
utils.defaultTypes = function defaultTypes (types) {
  types = typeof types === 'object' ? types : {}
  return utils.extend({
    multipart: [
      'multipart/form-data'
    ],
    text: [
      'text/*'
    ],
    form: [
      'application/x-www-form-urlencoded'
    ],
    json: [
      'application/json',
      'application/json-patch+json',
      'application/vnd.api+json',
      'application/csp-report'
    ],
    buffer: [
      'text/*'
    ]
  }, types)
}

/**
 * > Is "valid" request method, according to IETF Draft.
 *
 * @see   https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-19#section-6.1
 * @param  {String} `method` koa request method
 * @return {Boolean}
 * @api private
 */
utils.isValid = function isValid (method) {
  return ['GET', 'HEAD', 'DELETE'].indexOf(method.toUpperCase()) === -1
}

/**
 * > Add `koa-body-parsers` to the koa context. In addition
 * also adds the formidable as multipart parser.
 *
 * @param  {Object} `ctx` koa context
 * @param  {Object} `opts` default options
 * @return {Object} `ctx` koa context
 * @api private
 */
utils.setParsers = function setParsers (ctx, opts) {
  ctx.app.querystring = opts.querystring ||
    opts.qs || // alias
    ctx.app && ctx.app.querystring ||
    ctx.app && ctx.app.qs || // alias
    ctx.querystring ||
    ctx.qs // alias

  utils.bodyParsers(ctx)
  ctx.request.multipart = utils.multipart.bind(ctx)
  return ctx
}

/**
 * > Formidable wrapper as multipart parser to make
 * thunk that later can be yielded. Also allows you to pass
 * formidable.IncomingForm instance to `options.IncomingForm`.
 *
 * @param  {Object} `options` passed or default plugin options
 * @param  {Object} `ctx` koa context
 * @return {Function} thunk
 * @api private
 */
utils.multipart = function multipart (options) {
  var ctx = this

  return function thunk (done) {
    var buff = ''
    var fields = {}
    var files = []
    var form = options.IncomingForm instanceof utils.formidable.IncomingForm
      ? options.IncomingForm
      : new utils.formidable.IncomingForm(options)

    form.on('error', done)
    form.on('aborted', done)
    form.on('file', function (name, value) {
      files.push(value)
      fields[name] = fields[name] || []
      fields[name].push(value)
    })
    form.on('field', function (name, value) {
      buff += name + '=' + value + '&'
    })
    form.on('end', function () {
      fields = buff && buff.length
        ? utils.extend({}, utils.parseQs(buff.slice(0, -1), options), fields)
        : fields

      done(null, {
        fields: fields,
        files: files
      })
    })
    form.parse(ctx.req)
  }
}

/**
 * > Parse a different type of request bodies. By default accepts
 * and can parse JSON, JSON-API, JSON-Patch, text, form, urlencoded
 * and buffer bodies.
 *
 * @param {Object}   `ctx` koa context
 * @param {Object}   `options` plugin options
 * @param {Function} `next` next middleware
 * @api private
 */
utils.parseBody = function * parseBody (ctx, options, next) { /* eslint complexity: [2, 12] */
  var fields = typeof options.fields === 'string' ? options.fields : 'fields'
  var files = typeof options.files === 'string' ? options.files : 'files'
  var custom = options.extendTypes.custom

  if (custom && custom.length && ctx.request.is(custom)) {
    yield * options.handler.call(ctx, ctx, options, next)
    return yield * next
  }
  if (options.detectJSON(ctx) || ctx.request.is(options.extendTypes.json)) {
    ctx.app.jsonStrict = typeof options.jsonStrict === 'boolean' ? options.jsonStrict : true
    ctx.request[fields] = yield ctx.request.json(options.jsonLimit)
    return yield * next
  }
  if (ctx.request.is(options.extendTypes.form || options.extendTypes.urlencoded)) {
    var res = yield ctx.request.urlencoded(options.formLimit)
    ctx.request[fields] = res
    return yield * next
  }
  if (options.buffer && ctx.request.is(options.extendTypes.buffer)) {
    ctx.request.body = yield ctx.request.buffer(options.bufferLimit)
    return yield * next
  }
  if (ctx.request.is(options.extendTypes.text)) {
    var limit = options.textLimit
    var body = yield ctx.request.text(limit)

    ctx.request.body = body
    return yield * next
  }
  if (options.multipart && ctx.request.is(options.extendTypes.multipart)) {
    var result = yield ctx.request.multipart(options)
    ctx.request[fields] = result.fields
    ctx.request[files] = result.files
    return yield * next
  }
}

/**
 * Expose `utils` modules
 */

module.exports = utils
<commit_msg>fix(utils.js): qs: query string parsing options<commit_after>'use strict'

/**
 * Module dependencies
 */

var utils = require('lazy-cache')(require)

/**
 * Temporarily re-assign `require` to trick browserify and
 * webpack into reconizing lazy dependencies.
 *
 * This tiny bit of ugliness has the huge dual advantage of
 * only loading modules that are actually called at some
 * point in the lifecycle of the application, whilst also
 * allowing browserify and webpack to find modules that
 * are depended on but never actually called.
 */

var fn = require
require = utils // eslint-disable-line no-undef, no-native-reassign, no-global-assign

/**
 * Lazily required module dependencies
 */

require('extend-shallow', 'extend')
require('formidable')
require('koa-body-parsers', 'bodyParsers')
require('querystring')

/**
 * Restore `require`
 */

require = fn // eslint-disable-line no-undef, no-native-reassign, no-global-assign

/**
 * > Patch querystring logic. By default uses node's
 * built-in `querystring` module, otherwise that is
 * provided from `opts.querystring`. Works well with
 * the `qs` module. You can pass it like that
 *
 * **Example**
 *
 * ```js
 * app.use(body({
 *   querystring: require('qs')
 * }))
 * ```
 *
 * @param  {String} `str` querystring
 * @param  {Object} `opts` loaded options
 * @return {Object} parsed querystring object
 * @api private
 */
utils.parseQs = function parseQs (str, opts) {
  return opts.querystring
    ? opts.querystring.parse(str, opts)
    : utils.querystring.parse(str, opts.delimiter, '=', opts)
}

/**
 * > Default options that will be loaded. Pass `options` to overwrite them.
 *
 * @param  {Object} `options`
 * @return {Object}
 * @api private
 */
utils.defaultOptions = function defaultOptions (options) {
  options = typeof options === 'object' ? options : {}
  var types = utils.defaultTypes(options.extendTypes)
  options = utils.extend({
    fields: false,
    files: false,
    multipart: true,
    textLimit: false,
    formLimit: false,
    jsonLimit: false,
    jsonStrict: true,
    detectJSON: false,
    bufferLimit: false,
    buffer: false,
    strict: true,

    // query string `parse` options
    delimiter: '&',
    decodeURIComponent: utils.querystring.unescape,
    maxKeys: 1000
  }, options)

  options.delimiter = options.sep || options.delimiter
  options.formLimit = options.formLimit || options.urlencodedLimit
  options.extendTypes = types
  options.onerror = options.onЕrror || options.onerror
  options.onerror = typeof options.onerror === 'function'
    ? options.onerror
    : false
  options.delimiter = typeof options.delimiter === 'string'
    ? options.delimiter
    : '&'

  if (typeof options.handler !== 'function') {
    options.handler = function * noopHandler () {}
  }
  if (typeof options.detectJSON !== 'function') {
    options.detectJSON = function detectJSON () {
      return false
    }
  }

  return options
}

/**
 * > Only extend/overwrite default accept types.
 *
 * @param  {Object} `types`
 * @return {Object}
 * @api private
 */
utils.defaultTypes = function defaultTypes (types) {
  types = typeof types === 'object' ? types : {}
  return utils.extend({
    multipart: [
      'multipart/form-data'
    ],
    text: [
      'text/*'
    ],
    form: [
      'application/x-www-form-urlencoded'
    ],
    json: [
      'application/json',
      'application/json-patch+json',
      'application/vnd.api+json',
      'application/csp-report'
    ],
    buffer: [
      'text/*'
    ]
  }, types)
}

/**
 * > Is "valid" request method, according to IETF Draft.
 *
 * @see   https://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-19#section-6.1
 * @param  {String} `method` koa request method
 * @return {Boolean}
 * @api private
 */
utils.isValid = function isValid (method) {
  return ['GET', 'HEAD', 'DELETE'].indexOf(method.toUpperCase()) === -1
}

/**
 * > Add `koa-body-parsers` to the koa context. In addition
 * also adds the formidable as multipart parser.
 *
 * @param  {Object} `ctx` koa context
 * @param  {Object} `opts` default options
 * @return {Object} `ctx` koa context
 * @api private
 */
utils.setParsers = function setParsers (ctx, opts) {
  ctx.app.querystring = opts.querystring ||
    opts.qs || // alias
    ctx.app && ctx.app.querystring ||
    ctx.app && ctx.app.qs || // alias
    ctx.querystring ||
    ctx.qs // alias

  utils.bodyParsers(ctx)
  ctx.request.multipart = utils.multipart.bind(ctx)
  return ctx
}

/**
 * > Formidable wrapper as multipart parser to make
 * thunk that later can be yielded. Also allows you to pass
 * formidable.IncomingForm instance to `options.IncomingForm`.
 *
 * @param  {Object} `options` passed or default plugin options
 * @param  {Object} `ctx` koa context
 * @return {Function} thunk
 * @api private
 */
utils.multipart = function multipart (options) {
  var ctx = this

  return function thunk (done) {
    var buff = ''
    var fields = {}
    var files = []
    var form = options.IncomingForm instanceof utils.formidable.IncomingForm
      ? options.IncomingForm
      : new utils.formidable.IncomingForm(options)

    form.on('error', done)
    form.on('aborted', done)
    form.on('file', function (name, value) {
      files.push(value)
      fields[name] = fields[name] || []
      fields[name].push(value)
    })
    form.on('field', function (name, value) {
      buff += name + '=' + value + options.delimiter
    })
    form.on('end', function () {
      fields = buff && buff.length
        ? utils.extend({}, utils.parseQs(buff.slice(0, -1), options), fields)
        : fields

      done(null, {
        fields: fields,
        files: files
      })
    })
    form.parse(ctx.req)
  }
}

/**
 * > Parse a different type of request bodies. By default accepts
 * and can parse JSON, JSON-API, JSON-Patch, text, form, urlencoded
 * and buffer bodies.
 *
 * @param {Object}   `ctx` koa context
 * @param {Object}   `options` plugin options
 * @param {Function} `next` next middleware
 * @api private
 */
utils.parseBody = function * parseBody (ctx, options, next) { /* eslint complexity: [2, 12] */
  var fields = typeof options.fields === 'string' ? options.fields : 'fields'
  var files = typeof options.files === 'string' ? options.files : 'files'
  var custom = options.extendTypes.custom

  if (custom && custom.length && ctx.request.is(custom)) {
    yield * options.handler.call(ctx, ctx, options, next)
    return yield * next
  }
  if (options.detectJSON(ctx) || ctx.request.is(options.extendTypes.json)) {
    ctx.app.jsonStrict = typeof options.jsonStrict === 'boolean' ? options.jsonStrict : true
    ctx.request[fields] = yield ctx.request.json(options.jsonLimit)
    return yield * next
  }
  if (ctx.request.is(options.extendTypes.form || options.extendTypes.urlencoded)) {
    var res = yield ctx.request.urlencoded(options.formLimit)
    ctx.request[fields] = res
    return yield * next
  }
  if (options.buffer && ctx.request.is(options.extendTypes.buffer)) {
    ctx.request.body = yield ctx.request.buffer(options.bufferLimit)
    return yield * next
  }
  if (ctx.request.is(options.extendTypes.text)) {
    var limit = options.textLimit
    var body = yield ctx.request.text(limit)

    ctx.request.body = body
    return yield * next
  }
  if (options.multipart && ctx.request.is(options.extendTypes.multipart)) {
    var result = yield ctx.request.multipart(options)
    ctx.request[fields] = result.fields
    ctx.request[files] = result.files
    return yield * next
  }
}

/**
 * Expose `utils` modules
 */

module.exports = utils
<|endoftext|>