<commit_before>/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @flow
 */
'use strict';

import type {HasteContext} from 'types/HasteMap';
import type {Config} from 'types/Config';

const ansiEscapes = require('ansi-escapes');
const chalk = require('chalk');
const createHasteContext = require('./lib/createHasteContext');
const HasteMap = require('jest-haste-map');
const preRunMessage = require('./preRunMessage');
const patternMode = require('./patternMode');
const runJest = require('./runJest');
const setWatchMode = require('./lib/setWatchMode');
const SearchSource = require('./SearchSource');
const TestWatcher = require('./TestWatcher');
const {KEYS, CLEAR} = require('./constants');

const watch = (
  config: Config,
  pipe: stream$Writable | tty$WriteStream,
  argv: Object,
  hasteMap: HasteMap,
  hasteContext: HasteContext,
  stdin?: stream$Readable | tty$ReadStream = process.stdin
) => {
  setWatchMode(argv, argv.watch ? 'watch' : 'watchAll', {
    pattern: argv._,
  });
  let currentPattern = '';
  let hasSnapshotFailure = false;
  let isEnteringPattern = false;
  let isRunning = false;
  let testWatcher;
  let displayHelp = true;
  let searchSource = new SearchSource(hasteContext, config);

  hasteMap.on('change', ({hasteFS, moduleMap}) => {
    hasteContext = createHasteContext(config, {hasteFS, moduleMap});
    currentPattern = '';
    isEnteringPattern = false;
    searchSource = new SearchSource(hasteContext, config);
    startRun();
  });

  process.on('exit', () => {
    if (isEnteringPattern) {
      pipe.write(ansiEscapes.cursorDown());
      pipe.write(ansiEscapes.eraseDown);
    }
  });

  const writeCurrentPattern = () => {
    let regex;

    try {
      regex = new RegExp(currentPattern, 'i');
    } catch (e) {}

    const paths = regex ?
      searchSource.findMatchingTests(currentPattern).paths : [];

    pipe.write(ansiEscapes.eraseLine);
    pipe.write(ansiEscapes.cursorLeft);
    patternMode.printTypeahead(config, pipe, currentPattern, paths);
  };

  const startRun = (overrideConfig: Object = {}) => {
    if (isRunning) {
      return null;
    }

    testWatcher = new TestWatcher({isWatchMode: true});
    pipe.write(CLEAR);<commit_msg>Filter snap file changes in watch mode (#2833)<commit_after>/**
 * Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @flow
 */
'use strict';

import type {HasteContext} from 'types/HasteMap';
import type {Config} from 'types/Config';

const ansiEscapes = require('ansi-escapes');
const chalk = require('chalk');
const createHasteContext = require('./lib/createHasteContext');
const HasteMap = require('jest-haste-map');
const preRunMessage = require('./preRunMessage');
const patternMode = require('./patternMode');
const runJest = require('./runJest');
const setWatchMode = require('./lib/setWatchMode');
const SearchSource = require('./SearchSource');
const TestWatcher = require('./TestWatcher');
const {KEYS, CLEAR} = require('./constants');

const SNAPSHOT_EXTENSION = 'snap';

const watch = (
  config: Config,
  pipe: stream$Writable | tty$WriteStream,
  argv: Object,
  hasteMap: HasteMap,
  hasteContext: HasteContext,
  stdin?: stream$Readable | tty$ReadStream = process.stdin
) => {
  setWatchMode(argv, argv.watch ? 'watch' : 'watchAll', {
    pattern: argv._,
  });
  let currentPattern = '';
  let hasSnapshotFailure = false;
  let isEnteringPattern = false;
  let isRunning = false;
  let testWatcher;
  let displayHelp = true;
  let searchSource = new SearchSource(hasteContext, config);

  hasteMap.on('change', ({eventsQueue, hasteFS, moduleMap}) => {
    const hasOnlySnapshotChanges = eventsQueue.every(({filePath}) => {
      return filePath.endsWith(`.${SNAPSHOT_EXTENSION}`);
    });

    if (!hasOnlySnapshotChanges) {
      hasteContext =  createHasteContext(config, {hasteFS, moduleMap});
      currentPattern = '';
      isEnteringPattern = false;
      searchSource = new SearchSource(hasteContext, config);
      startRun();
    }
  });

  process.on('exit', () => {
    if (isEnteringPattern) {
      pipe.write(ansiEscapes.cursorDown());
      pipe.write(ansiEscapes.eraseDown);
    }
  });

  const writeCurrentPattern = () => {
    let regex;

    try {
      regex = new RegExp(currentPattern, 'i');
    } catch (e) {}

    const paths = regex ?
      searchSource.findMatchingTests(currentPattern).paths : [];

    pipe.write(ansiEscapes.eraseLine);
    pipe.write(ansiEscapes.cursorLeft);
    patternMode.printTypeahead(config, pipe, currentPattern, paths);
  };

  const startRun = (overrideConfig: Object = {}) => {
    if (isRunning) {
      return null;
    }

    testWatcher = new TestWatcher({isWatchMode: true});
    pipe.write(CLEAR);
{'fraction_non_alphanumeric': 0.13569776407093292, 'fraction_numerical': 0.002313030069390902, 'mean_word_length': 4.047665369649805, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1530852', 'n_tokens_mistral': 1614, 'n_tokens_neox': 1570, 'n_words': 403}