Best JavaScript code snippet using storybook-root
mtime_file_watcher_test.py
Source:mtime_file_watcher_test.py  
1#!/usr/bin/env python2#3# Copyright 2007 Google Inc.4#5# Licensed under the Apache License, Version 2.0 (the "License");6# you may not use this file except in compliance with the License.7# You may obtain a copy of the License at8#9#     http://www.apache.org/licenses/LICENSE-2.010#11# Unless required by applicable law or agreed to in writing, software12# distributed under the License is distributed on an "AS IS" BASIS,13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.14# See the License for the specific language governing permissions and15# limitations under the License.16#17"""Tests for google.appengine.tools.devappserver2.mtime_file_watcher."""18import os19import os.path20import re21import shutil22import tempfile23import time24import unittest25from google.appengine.tools.devappserver2 import mtime_file_watcher26def _sync():27  time.sleep(.1)  # just to stay over the FS timestamp resolution28class TestMtimeFileWatcher(unittest.TestCase):29  """Tests for mtime_file_watcher.MtimeFileWatcher."""30  def setUp(self):31    self._directory = tempfile.mkdtemp()  # The watched directory32    self._junk_directory = tempfile.mkdtemp()  # A scrap directory.33    self._watcher = mtime_file_watcher.MtimeFileWatcher(self._directory)34  def tearDown(self):35    self._watcher.quit()36    shutil.rmtree(self._directory)37    shutil.rmtree(self._junk_directory)38  def _create_file(self, relative_path):39    realpath = os.path.realpath(os.path.join(self._directory, relative_path))40    with open(realpath, 'w'):41      pass42    return realpath43  def _create_directory(self, relative_path):44    realpath = os.path.realpath(os.path.join(self._directory, relative_path))45    os.mkdir(realpath)46    return realpath47  def test_file_created(self):48    self._watcher.start()49    self._watcher._startup_thread.join()50    path = self._create_file('test')51    self.assertEqual(self._watcher.changes(), {path})52  def test_skip_file_re(self):53    self._watcher.set_skip_files_re(re.compile('^.*skipped_file'))54    self._watcher.start()55    self._watcher._startup_thread.join()56    self._create_file('skipped_file')57    self.assertEqual(self._watcher.changes(), set())58    path = self._create_directory('subdir/')59    self.assertEqual(self._watcher.changes(), {path})60    path = self._create_file('subdir/skipped_file')61    # skip_files_re should also match subdirectories of watched directory.62    self.assertEqual(self._watcher.changes(), set())63    # Avoid polluting other tests.64    self._watcher.set_skip_files_re(None)65  def test_file_modified(self):66    path = self._create_file('test')67    _sync()68    self._watcher.start()69    self._watcher._startup_thread.join()70    with open(path, 'w') as f:71      f.write('testing')72    self.assertEqual(self._watcher.changes(), {path})73  def test_file_read(self):74    path = self._create_file('test')75    with open(path, 'w') as f:76      f.write('testing')77    self._watcher.start()78    self._watcher._startup_thread.join()79    with open(path, 'r') as f:80      f.read()81    # Reads should not trigger updates.82    self.assertEqual(self._watcher.changes(), set())83  def test_file_deleted(self):84    path = self._create_file('test')85    self._watcher.start()86    self._watcher._startup_thread.join()87    os.remove(path)88    self.assertEqual(self._watcher.changes(), {path})89  def test_file_renamed(self):90    source = self._create_file('test')91    target = os.path.join(os.path.dirname(source), 'test2')92    self._watcher.start()93    self._watcher._startup_thread.join()94    os.rename(source, target)95    self.assertEqual(self._watcher.changes(), {source, target})96  def test_create_directory(self):97    self._watcher.start()98    self._watcher._startup_thread.join()99    path = self._create_directory('test')100    self.assertEqual(self._watcher.changes(), {path})101  def test_skip_file_re_directory(self):102    self._watcher.set_skip_files_re(re.compile('.*skipped_dir'))103    self._watcher.start()104    self._watcher._startup_thread.join()105    self._create_directory('skipped_dir/')106    self.assertEqual(self._watcher.changes(), set())107    # If a directory is skipped, the files and directories in that directory108    # would also be skipped109    self._create_directory('skipped_dir/subdir/')110    self.assertEqual(self._watcher.changes(), set())111    path = self._create_directory('subdir/')112    self.assertEqual(self._watcher.changes(), {path})113    # skip_files_re should also match subdirectories of watched directory.114    path = self._create_directory('subdir/skipped_dir/')115    self.assertEqual(self._watcher.changes(), set())116    # Avoid polluting other tests.117    self._watcher.set_skip_files_re(None)118  def test_file_created_in_directory(self):119    self._create_directory('test')120    _sync()121    self._watcher.start()122    self._watcher._startup_thread.join()123    path = self._create_file('test/file')124    # Keep behavior consistency with inofiy_file_watcher,125    # parent directory of path should not be considered as changed.126    self.assertEqual(self._watcher.changes(), {path})127  def test_move_directory(self):128    source = self._create_directory('test')129    target = os.path.join(os.path.dirname(source), 'test2')130    self._watcher.start()131    self._watcher._startup_thread.join()132    os.rename(source, target)133    self.assertEqual(self._watcher.changes(), {source, target})134  def test_move_directory_out_of_watched(self):135    source = self._create_directory('test')136    target = os.path.join(self._junk_directory, 'test')137    self._watcher.start()138    self._watcher._startup_thread.join()139    os.rename(source, target)140    self.assertEqual(self._watcher.changes(), {source})141    with open(os.path.join(target, 'file'), 'w'):142      pass143    # Changes to files in subdirectories that have been moved should be ignored.144    self.assertEqual(self._watcher.changes(), set())145  def test_move_directory_into_watched(self):146    source = os.path.join(self._junk_directory, 'source')147    target = os.path.join(self._directory, 'target')148    os.mkdir(source)149    _sync()150    self._watcher.start()151    self._watcher._startup_thread.join()152    os.rename(source, target)153    self.assertEqual(self._watcher.changes(), {target})154    file_path = os.path.join(target, 'file')155    with open(file_path, 'w+'):156      pass157    # Keep behavior consistency with inofiy_file_watcher,158    # target should not be considered as changed.159    self.assertEqual(self._watcher.changes(), {file_path})160  def test_directory_deleted(self):161    path = self._create_directory('test')162    _sync()163    self._watcher.start()164    self._watcher._startup_thread.join()165    os.rmdir(path)166    self.assertEqual(self._watcher.changes(), {path})167  @unittest.skipUnless(hasattr(os, 'symlink'), 'requires os.symlink')168  def test_symlink(self):169    sym_target = os.path.join(self._directory, 'test')170    os.mkdir(os.path.join(self._junk_directory, 'subdir'))171    # the translated path in the target dir172    sym_subdir_path = os.path.join(sym_target, 'subdir')173    _sync()174    self._watcher.start()175    self._watcher._startup_thread.join()176    # Check that an added symlinked directory is reported.177    os.symlink(self._junk_directory, sym_target)178    self.assertEqual(179        self._watcher.changes(),180        {sym_target, os.path.join(sym_target, 'subdir')})181    # Check that a file added to the symlinked directory is reported.182    with open(os.path.join(self._junk_directory, 'file1'), 'w'):183      pass184    sym_file_path = os.path.join(sym_target, 'file1')185    # Keep behavior consistency with inofiy_file_watcher,186    # sym_target should not be considered as changed.187    self.assertEqual(188        self._watcher.changes(), {sym_file_path})189    # Check that a removed symlinked directory is reported.190    os.remove(sym_target)191    self.assertEqual(192        self._watcher.changes(), {sym_target, sym_file_path, sym_subdir_path})193    # Check that a file added to the removed symlinked directory is *not*194    # reported.195    with open(os.path.join(self._junk_directory, 'subdir', 'file2'), 'w'):196      pass197    self.assertEqual(self._watcher.changes(), set())198  def test_too_many_files(self):199    self._watcher.start()200    self._watcher._startup_thread.join()201    for i in range(10001):202      self._create_file('file%d' % i)203    self.assertEqual(len(self._watcher.changes()), 10000)204  @unittest.skipUnless(hasattr(os, 'symlink'), 'requires os.symlink')205  def test_symlink_loop(self):206    self._watcher.start()207    self._watcher._startup_thread.join()208    for i in range(1000):209      self._create_file('file%d' % i)210    for i in range(11):211      os.symlink(self._directory, os.path.join(self._directory, 'test%d' % i))212    # basically the set is completely crazy213    self.assertEqual(len(self._watcher.changes()), 10000)214if __name__ == '__main__':...watchEventSource.js
Source:watchEventSource.js  
1/*2	MIT License http://www.opensource.org/licenses/mit-license.php3	Author Tobias Koppers @sokra4*/5"use strict";6const fs = require("fs");7const path = require("path");8const { EventEmitter } = require("events");9const reducePlan = require("./reducePlan");10const IS_OSX = require("os").platform() === "darwin";11const IS_WIN = require("os").platform() === "win32";12const SUPPORTS_RECURSIVE_WATCHING = IS_OSX || IS_WIN;13const watcherLimit =14	+process.env.WATCHPACK_WATCHER_LIMIT || (IS_OSX ? 2000 : 10000);15const recursiveWatcherLogging = !!process.env16	.WATCHPACK_RECURSIVE_WATCHER_LOGGING;17let isBatch = false;18let watcherCount = 0;19/** @type {Map<Watcher, string>} */20const pendingWatchers = new Map();21/** @type {Map<string, RecursiveWatcher>} */22const recursiveWatchers = new Map();23/** @type {Map<string, DirectWatcher>} */24const directWatchers = new Map();25/** @type {Map<Watcher, RecursiveWatcher | DirectWatcher>} */26const underlyingWatcher = new Map();27class DirectWatcher {28	constructor(filePath) {29		this.filePath = filePath;30		this.watchers = new Set();31		this.watcher = undefined;32		try {33			const watcher = fs.watch(filePath);34			this.watcher = watcher;35			watcher.on("change", (type, filename) => {36				for (const w of this.watchers) {37					w.emit("change", type, filename);38				}39			});40			watcher.on("error", error => {41				for (const w of this.watchers) {42					w.emit("error", error);43				}44			});45		} catch (err) {46			process.nextTick(() => {47				for (const w of this.watchers) {48					w.emit("error", err);49				}50			});51		}52		watcherCount++;53	}54	add(watcher) {55		underlyingWatcher.set(watcher, this);56		this.watchers.add(watcher);57	}58	remove(watcher) {59		this.watchers.delete(watcher);60		if (this.watchers.size === 0) {61			directWatchers.delete(this.filePath);62			watcherCount--;63			if (this.watcher) this.watcher.close();64		}65	}66	getWatchers() {67		return this.watchers;68	}69}70class RecursiveWatcher {71	constructor(rootPath) {72		this.rootPath = rootPath;73		/** @type {Map<Watcher, string>} */74		this.mapWatcherToPath = new Map();75		/** @type {Map<string, Set<Watcher>>} */76		this.mapPathToWatchers = new Map();77		this.watcher = undefined;78		try {79			const watcher = fs.watch(rootPath, {80				recursive: true81			});82			this.watcher = watcher;83			watcher.on("change", (type, filename) => {84				if (!filename) {85					if (recursiveWatcherLogging) {86						process.stderr.write(87							`[watchpack] dispatch ${type} event in recursive watcher (${88								this.rootPath89							}) to all watchers\n`90						);91					}92					for (const w of this.mapWatcherToPath.keys()) {93						w.emit("change", type);94					}95				} else {96					const dir = path.dirname(filename);97					const watchers = this.mapPathToWatchers.get(dir);98					if (recursiveWatcherLogging) {99						process.stderr.write(100							`[watchpack] dispatch ${type} event in recursive watcher (${101								this.rootPath102							}) for '${filename}' to ${103								watchers ? watchers.size : 0104							} watchers\n`105						);106					}107					if (watchers === undefined) return;108					for (const w of watchers) {109						w.emit("change", type, path.basename(filename));110					}111				}112			});113			watcher.on("error", error => {114				for (const w of this.mapWatcherToPath.keys()) {115					w.emit("error", error);116				}117			});118		} catch (err) {119			process.nextTick(() => {120				for (const w of this.mapWatcherToPath.keys()) {121					w.emit("error", err);122				}123			});124		}125		watcherCount++;126		if (recursiveWatcherLogging) {127			process.stderr.write(128				`[watchpack] created recursive watcher at ${rootPath}\n`129			);130		}131	}132	add(filePath, watcher) {133		underlyingWatcher.set(watcher, this);134		const subpath = filePath.slice(this.rootPath.length + 1) || ".";135		this.mapWatcherToPath.set(watcher, subpath);136		const set = this.mapPathToWatchers.get(subpath);137		if (set === undefined) {138			const newSet = new Set();139			newSet.add(watcher);140			this.mapPathToWatchers.set(subpath, newSet);141		} else {142			set.add(watcher);143		}144	}145	remove(watcher) {146		const subpath = this.mapWatcherToPath.get(watcher);147		if (!subpath) return;148		this.mapWatcherToPath.delete(watcher);149		const set = this.mapPathToWatchers.get(subpath);150		set.delete(watcher);151		if (set.size === 0) {152			this.mapPathToWatchers.delete(subpath);153		}154		if (this.mapWatcherToPath.size === 0) {155			recursiveWatchers.delete(this.rootPath);156			watcherCount--;157			if (this.watcher) this.watcher.close();158			if (recursiveWatcherLogging) {159				process.stderr.write(160					`[watchpack] closed recursive watcher at ${this.rootPath}\n`161				);162			}163		}164	}165	getWatchers() {166		return this.mapWatcherToPath;167	}168}169class Watcher extends EventEmitter {170	close() {171		if (pendingWatchers.has(this)) {172			pendingWatchers.delete(this);173			return;174		}175		const watcher = underlyingWatcher.get(this);176		watcher.remove(this);177		underlyingWatcher.delete(this);178	}179}180const createDirectWatcher = filePath => {181	const existing = directWatchers.get(filePath);182	if (existing !== undefined) return existing;183	const w = new DirectWatcher(filePath);184	directWatchers.set(filePath, w);185	return w;186};187const createRecursiveWatcher = rootPath => {188	const existing = recursiveWatchers.get(rootPath);189	if (existing !== undefined) return existing;190	const w = new RecursiveWatcher(rootPath);191	recursiveWatchers.set(rootPath, w);192	return w;193};194const execute = () => {195	/** @type {Map<string, Watcher[] | Watcher>} */196	const map = new Map();197	const addWatcher = (watcher, filePath) => {198		const entry = map.get(filePath);199		if (entry === undefined) {200			map.set(filePath, watcher);201		} else if (Array.isArray(entry)) {202			entry.push(watcher);203		} else {204			map.set(filePath, [entry, watcher]);205		}206	};207	for (const [watcher, filePath] of pendingWatchers) {208		addWatcher(watcher, filePath);209	}210	pendingWatchers.clear();211	// Fast case when we are not reaching the limit212	if (!SUPPORTS_RECURSIVE_WATCHING || watcherLimit - watcherCount >= map.size) {213		// Create watchers for all entries in the map214		for (const [filePath, entry] of map) {215			const w = createDirectWatcher(filePath);216			if (Array.isArray(entry)) {217				for (const item of entry) w.add(item);218			} else {219				w.add(entry);220			}221		}222		return;223	}224	// Reconsider existing watchers to improving watch plan225	for (const watcher of recursiveWatchers.values()) {226		for (const [w, subpath] of watcher.getWatchers()) {227			addWatcher(w, path.join(watcher.rootPath, subpath));228		}229	}230	for (const watcher of directWatchers.values()) {231		for (const w of watcher.getWatchers()) {232			addWatcher(w, watcher.filePath);233		}234	}235	// Merge map entries to keep watcher limit236	// Create a 10% buffer to be able to enter fast case more often237	const plan = reducePlan(map, watcherLimit * 0.9);238	// Update watchers for all entries in the map239	for (const [filePath, entry] of plan) {240		if (entry.size === 1) {241			for (const [watcher, filePath] of entry) {242				const w = createDirectWatcher(filePath);243				const old = underlyingWatcher.get(watcher);244				if (old === w) continue;245				w.add(watcher);246				if (old !== undefined) old.remove(watcher);247			}248		} else {249			const filePaths = new Set(entry.values());250			if (filePaths.size > 1) {251				const w = createRecursiveWatcher(filePath);252				for (const [watcher, watcherPath] of entry) {253					const old = underlyingWatcher.get(watcher);254					if (old === w) continue;255					w.add(watcherPath, watcher);256					if (old !== undefined) old.remove(watcher);257				}258			} else {259				for (const filePath of filePaths) {260					const w = createDirectWatcher(filePath);261					for (const watcher of entry.keys()) {262						const old = underlyingWatcher.get(watcher);263						if (old === w) continue;264						w.add(watcher);265						if (old !== undefined) old.remove(watcher);266					}267				}268			}269		}270	}271};272exports.watch = filePath => {273	const watcher = new Watcher();274	// Find an existing watcher275	const directWatcher = directWatchers.get(filePath);276	if (directWatcher !== undefined) {277		directWatcher.add(watcher);278		return watcher;279	}280	let current = filePath;281	for (;;) {282		const recursiveWatcher = recursiveWatchers.get(current);283		if (recursiveWatcher !== undefined) {284			recursiveWatcher.add(filePath, watcher);285			return watcher;286		}287		const parent = path.dirname(current);288		if (parent === current) break;289		current = parent;290	}291	// Queue up watcher for creation292	pendingWatchers.set(watcher, filePath);293	if (!isBatch) execute();294	return watcher;295};296exports.batch = fn => {297	isBatch = true;298	try {299		fn();300	} finally {301		isBatch = false;302		execute();303	}304};305exports.getNumberOfWatchers = () => {306	return watcherCount;...file_watcher.py
Source:file_watcher.py  
...61    # Splits the allocated time between the watchers.62    timeout_ms /= len(self._file_watchers)63    return set.union(64        *[watcher.changes(timeout_ms) for watcher in self._file_watchers])65def _create_watcher(directories, watcher_class):66  """Creates the best watcher based on multiple directory support.67  For file watchers that can support multiple directories, directly instantiate68  an instance passing in an iterable of directories names. For file watchers69  that only support single directories, instantiate one directly if there is70  only a single directory to watch or wrap them in a MultipleFileWatcher if71  there are multiple directories to watch.72  Args:73    directories: An iterable of all the directories to watch.74    watcher_class: A callable that creates the per-directory FileWatcher75      instance. Must be callable with a single item of the type held by76      directories.77  Returns:78    A FileWatcher appropriate for the list of directories.79  """80  if watcher_class.SUPPORTS_MULTIPLE_DIRECTORIES:81    return watcher_class(directories)82  elif len(directories) == 1:83    return watcher_class(directories[0])84  else:85    return _MultipleFileWatcher([watcher_class(d) for d in directories])86def _create_linux_watcher(directories):87  """Create a watcher for Linux.88  While we prefer InotifyFileWatcher for Linux, there are only a limited number89  of inotify instances available per user (for example, 128 on a Goobuntu 12.0490  install). Try to create an InotifyFileWatcher but fall back on91  MTimeFileWatcher if the user is out of resources.92  Args:93    directories: A list representing the paths of the directories to monitor.94  Returns:95    An InotifyFileWatcher if the user has available resources and an96    MtimeFileWatcher if not.97  """98  # TODO: develop a way to check if the filesystem supports inotify.99  # (for example, NFS does not) and also use MTimeFileWatcher in that case.100  try:101    return _create_watcher(directories,102                           inotify_file_watcher.InotifyFileWatcher)103  except OSError as e:104    logging.warning('Could not create InotifyFileWatcher;'105                    ' falling back to MTimeFileWatcher: %s', e)106    return _create_watcher(directories, mtime_file_watcher.MtimeFileWatcher)107def get_file_watcher(directories, use_mtime_file_watcher):108  """Returns an instance that monitors a hierarchy of directories.109  Args:110    directories: A list representing the paths of the directories to monitor.111    use_mtime_file_watcher: A bool containing whether to use mtime polling to112        monitor file changes even if other options are available on the current113        platform.114  Returns:115    A FileWatcher appropriate for the current platform. start() must be called116    before changes().117  """118  assert not isinstance(directories, types.StringTypes), 'expected list got str'119  if use_mtime_file_watcher:120    return _create_watcher(directories, mtime_file_watcher.MtimeFileWatcher)121  elif sys.platform.startswith('linux'):122    return _create_linux_watcher(directories)123  elif sys.platform.startswith('win'):124    return _create_watcher(directories, win32_file_watcher.Win32FileWatcher)125  else:126    return _create_watcher(directories, mtime_file_watcher.MtimeFileWatcher)127  # NOTE: The Darwin-specific watcher implementation (found in the deleted file128  # fsevents_file_watcher.py) was incorrect - the Mac OS X FSEvents129  # implementation does not detect changes in symlinked files or directories. It130  # also does not provide file-level change precision before Mac OS 10.7.131  #132  # It is still possible to provide an efficient implementation by watching all133  # symlinked directories and using mtime checking for symlinked files. On any134  # change in a directory, it would have to be rescanned to see if a new135  # symlinked file or directory was added. It also might be possible to use...watcher.spec.js
Source:watcher.spec.js  
1import Vue from 'vue'2import Watcher from 'core/observer/watcher'3describe('Watcher', () => {4  let vm, spy5  beforeEach(() => {6    vm = new Vue({7      template: '<div></div>',8      data: {9        a: 1,10        b: {11          c: 2,12          d: 413        },14        c: 'c',15        msg: 'yo'16      }17    }).$mount()18    spy = jasmine.createSpy('watcher')19  })20  it('path', done => {21    const watcher = new Watcher(vm, 'b.c', spy)22    expect(watcher.value).toBe(2)23    vm.b.c = 324    waitForUpdate(() => {25      expect(watcher.value).toBe(3)26      expect(spy).toHaveBeenCalledWith(3, 2)27      vm.b = { c: 4 } // swapping the object28    }).then(() => {29      expect(watcher.value).toBe(4)30      expect(spy).toHaveBeenCalledWith(4, 3)31    }).then(done)32  })33  it('non-existent path, set later', done => {34    const watcher1 = new Watcher(vm, 'b.e', spy)35    expect(watcher1.value).toBeUndefined()36    // check $add should not affect isolated children37    const child2 = new Vue({ parent: vm })38    const watcher2 = new Watcher(child2, 'b.e', spy)39    expect(watcher2.value).toBeUndefined()40    Vue.set(vm.b, 'e', 123)41    waitForUpdate(() => {42      expect(watcher1.value).toBe(123)43      expect(watcher2.value).toBeUndefined()44      expect(spy.calls.count()).toBe(1)45      expect(spy).toHaveBeenCalledWith(123, undefined)46    }).then(done)47  })48  it('delete', done => {49    const watcher = new Watcher(vm, 'b.c', spy)50    expect(watcher.value).toBe(2)51    Vue.delete(vm.b, 'c')52    waitForUpdate(() => {53      expect(watcher.value).toBeUndefined()54      expect(spy).toHaveBeenCalledWith(undefined, 2)55    }).then(done)56  })57  it('path containing $data', done => {58    const watcher = new Watcher(vm, '$data.b.c', spy)59    expect(watcher.value).toBe(2)60    vm.b = { c: 3 }61    waitForUpdate(() => {62      expect(watcher.value).toBe(3)63      expect(spy).toHaveBeenCalledWith(3, 2)64      vm.$data.b.c = 465    }).then(() => {66      expect(watcher.value).toBe(4)67      expect(spy).toHaveBeenCalledWith(4, 3)68    }).then(done)69  })70  it('deep watch', done => {71    let oldB72    new Watcher(vm, 'b', spy, {73      deep: true74    })75    vm.b.c = { d: 4 }76    waitForUpdate(() => {77      expect(spy).toHaveBeenCalledWith(vm.b, vm.b)78      oldB = vm.b79      vm.b = { c: [{ a: 1 }] }80    }).then(() => {81      expect(spy).toHaveBeenCalledWith(vm.b, oldB)82      expect(spy.calls.count()).toBe(2)83      vm.b.c[0].a = 284    }).then(() => {85      expect(spy).toHaveBeenCalledWith(vm.b, vm.b)86      expect(spy.calls.count()).toBe(3)87    }).then(done)88  })89  it('deep watch $data', done => {90    new Watcher(vm, '$data', spy, {91      deep: true92    })93    vm.b.c = 394    waitForUpdate(() => {95      expect(spy).toHaveBeenCalledWith(vm.$data, vm.$data)96    }).then(done)97  })98  it('deep watch with circular references', done => {99    new Watcher(vm, 'b', spy, {100      deep: true101    })102    Vue.set(vm.b, '_', vm.b)103    waitForUpdate(() => {104      expect(spy).toHaveBeenCalledWith(vm.b, vm.b)105      expect(spy.calls.count()).toBe(1)106      vm.b._.c = 1107    }).then(() => {108      expect(spy).toHaveBeenCalledWith(vm.b, vm.b)109      expect(spy.calls.count()).toBe(2)110    }).then(done)111  })112  it('fire change for prop addition/deletion in non-deep mode', done => {113    new Watcher(vm, 'b', spy)114    Vue.set(vm.b, 'e', 123)115    waitForUpdate(() => {116      expect(spy).toHaveBeenCalledWith(vm.b, vm.b)117      expect(spy.calls.count()).toBe(1)118      Vue.delete(vm.b, 'e')119    }).then(() => {120      expect(spy.calls.count()).toBe(2)121    }).then(done)122  })123  it('watch function', done => {124    const watcher = new Watcher(vm, function () {125      return this.a + this.b.d126    }, spy)127    expect(watcher.value).toBe(5)128    vm.a = 2129    waitForUpdate(() => {130      expect(spy).toHaveBeenCalledWith(6, 5)131      vm.b = { d: 2 }132    }).then(() => {133      expect(spy).toHaveBeenCalledWith(4, 6)134    }).then(done)135  })136  it('lazy mode', done => {137    const watcher = new Watcher(vm, function () {138      return this.a + this.b.d139    }, null, { lazy: true })140    expect(watcher.lazy).toBe(true)141    expect(watcher.value).toBeUndefined()142    expect(watcher.dirty).toBe(true)143    watcher.evaluate()144    expect(watcher.value).toBe(5)145    expect(watcher.dirty).toBe(false)146    vm.a = 2147    waitForUpdate(() => {148      expect(watcher.value).toBe(5)149      expect(watcher.dirty).toBe(true)150      watcher.evaluate()151      expect(watcher.value).toBe(6)152      expect(watcher.dirty).toBe(false)153    }).then(done)154  })155  it('teardown', done => {156    const watcher = new Watcher(vm, 'b.c', spy)157    watcher.teardown()158    vm.b.c = 3159    waitForUpdate(() => {160      expect(watcher.active).toBe(false)161      expect(spy).not.toHaveBeenCalled()162    }).then(done)163  })164  it('warn not support path', () => {165    new Watcher(vm, 'd.e + c', spy)166    expect('Failed watching path:').toHaveBeenWarned()167  })...browser_watcher.gypi
Source:browser_watcher.gypi  
1# Copyright (c) 2014 The Chromium Authors. All rights reserved.2# Use of this source code is governed by a BSD-style license that can be3# found in the LICENSE file.4{5  'conditions': [6  ['OS=="win"', {7      'targets': [8          {9            # This is a separate lib to minimize the dependencies for its10            # hosting binary "chrome_watcher.dll".11            'target_name': 'browser_watcher',12            'type': 'static_library',13            'sources': [14              'browser_watcher/endsession_watcher_window_win.cc',15              'browser_watcher/endsession_watcher_window_win.h',16              'browser_watcher/exit_code_watcher_win.cc',17              'browser_watcher/exit_code_watcher_win.h',18              'browser_watcher/exit_funnel_win.cc',19              'browser_watcher/exit_funnel_win.h',20              'browser_watcher/window_hang_monitor_win.cc',21              'browser_watcher/window_hang_monitor_win.h',22            ],23            'dependencies': [24              '../base/base.gyp:base',25            ],26          },27          {28            # Users of the watcher link this target.29            'target_name': 'browser_watcher_client',30            'type': 'static_library',31            'sources': [32              'browser_watcher/crash_reporting_metrics_win.cc',33              'browser_watcher/crash_reporting_metrics_win.h',34              'browser_watcher/watcher_client_win.cc',35              'browser_watcher/watcher_client_win.h',36              'browser_watcher/watcher_metrics_provider_win.cc',37              'browser_watcher/watcher_metrics_provider_win.h',38            ],39            'dependencies': [40              '../base/base.gyp:base',41            ],42          },43        ],44      }45    ],46  ],...getWatcherManager.js
Source:getWatcherManager.js  
1/*2	MIT License http://www.opensource.org/licenses/mit-license.php3	Author Tobias Koppers @sokra4*/5"use strict";6const path = require("path");7const DirectoryWatcher = require("./DirectoryWatcher");8class WatcherManager {9	constructor(options) {10		this.options = options;11		this.directoryWatchers = new Map();12	}13	getDirectoryWatcher(directory) {14		const watcher = this.directoryWatchers.get(directory);15		if (watcher === undefined) {16			const newWatcher = new DirectoryWatcher(this, directory, this.options);17			this.directoryWatchers.set(directory, newWatcher);18			newWatcher.on("closed", () => {19				this.directoryWatchers.delete(directory);20			});21			return newWatcher;22		}23		return watcher;24	}25	watchFile(p, startTime) {26		const directory = path.dirname(p);27		if (directory === p) return null;28		return this.getDirectoryWatcher(directory).watch(p, startTime);29	}30	watchDirectory(directory, startTime) {31		return this.getDirectoryWatcher(directory).watch(directory, startTime);32	}33}34const watcherManagers = new WeakMap();35/**36 * @param {object} options options37 * @returns {WatcherManager} the watcher manager38 */39module.exports = options => {40	const watcherManager = watcherManagers.get(options);41	if (watcherManager !== undefined) return watcherManager;42	const newWatcherManager = new WatcherManager(options);43	watcherManagers.set(options, newWatcherManager);44	return newWatcherManager;45};...Using AI Code Generation
1import { addDecorator, configure } from '@storybook/react';2import { withRootDecorator } from 'storybook-root-decorator';3addDecorator(withRootDecorator);4configure(require.context('../src', true, /\.stories\.js$/), module);5import React from 'react';6import { storiesOf } from '@storybook/react';7import { withRootDecorator } from 'storybook-root-decorator';8import { Button } from '@storybook/react/demo';9storiesOf('Root', module)10  .addDecorator(withRootDecorator)11  .add('with text', () => <Button>Hello Button</Button>);12import { addDecorator, configure } from '@storybook/react';13import { withRootDecorator } from 'storybook-root-decorator';14addDecorator(withRootDecorator);15configure(require.context('../src', true, /\.stories\.js$/), module);Using AI Code Generation
1import { watcher } from 'storybook-root';2import { storiesOf } from '@storybook/react';3import { action } from '@storybook/addon-actions';4watcher.on('change', action('file changed'));5storiesOf('Test', module).add('test', () => <div>hello</div>);6import chokidar from 'chokidar';7import EventEmitter from 'events';8const watcher = chokidar.watch('./test.js');9const emitter = new EventEmitter();10watcher.on('change', () => emitter.emit('change'));11export { emitter as watcher };12import { configure } from '@storybook/react';13const req = require.context('../src', true, /\.stories\.js$/);14function loadStories() {15  req.keys().forEach(filename => req(filename));16}17configure(loadStories, module);18import '@storybook/addon-actions/register';19{20  "scripts": {21  },22  "devDependencies": {23  }24}Using AI Code Generation
1const storybook = require('@storybook/react/standalone');2storybook({3});4const storybook = require('@storybook/react/standalone');5storybook({6});7const storybook = require('@storybook/react/standalone');8storybook({9});10const storybook = require('@storybook/react/standalone');11storybook({12});13const storybook = require('@storybook/react/standalone');14storybook({15});16const storybook = require('@storybook/react/standalone');17storybook({18});19const storybook = require('@storybook/react/standalone');20storybook({21});22const storybook = require('@storybook/react/standalone');23storybook({24});25const storybook = require('@storybook/react/standalone');26storybook({Using AI Code Generation
1import { watch } from 'storybook-root';2watch();3module.exports = {4};5import { addDecorator } from '@storybook/react';6import { withKnobs } from '@storybook/addon-knobs';7import { withInfo } from '@storybook/addon-info';8addDecorator(withKnobs);9addDecorator(withInfo);10const path = require('path');11module.exports = ({ config }) => {12  config.resolve.modules.push(path.resolve(__dirname, '../'));13  return config;14};15module.exports = {16};17{18  "compilerOptions": {19    "paths": {20    }21  },22}23{24  "compilerOptions": {Using AI Code Generation
1import { init } from './storybook-root';2init();3import { init, watch } from './storybook-root';4init();5watch();6import { init, watch, start } from './storybook-root';7init();8watch();9start();10import { init, watch, start, build } from './storybook-root';11init();12watch();13start();14build();15import { init, watch, start, build, buildStatic } from './storybook-root';16init();17watch();18start();19build();20buildStatic();21import { init, watch, start, build, buildStatic, buildStaticStandalone } from './storybook-root';22init();23watch();24start();25build();26buildStatic();27buildStaticStandalone();28import { init, watch, start, build, buildStatic, buildStaticStandalone, getStorybook } from './storybook-root';29init();30watch();31start();32build();33buildStatic();34buildStaticStandalone();35getStorybook();36import { init, watch, start, build, buildStatic, buildStaticStandalone, getStorybook, getStorybookUI } from './storybook-root';37init();38watch();39start();40build();41buildStatic();42buildStaticStandalone();43getStorybook();44getStorybookUI();45import { init, watch, start, build, buildStatic, buildStaticStandalone, getStorybook, getStorybookUI, getStorybookUIRoot } from './storybook-root';46init();47watch();48start();49build();50buildStatic();51buildStaticStandalone();52getStorybook();53getStorybookUI();54getStorybookUIRoot();55import { init, watch, start, build, buildStatic, buildStaticStandalone, getStorybook, getStorybookUI, getStorybookUIRoot, configure } from './storybook-root';56init();57watch();58start();59build();60buildStatic();61buildStaticStandalone();62getStorybook();63getStorybookUI();64getStorybookUIRoot();65configure();66import { init, watch, startUsing AI Code Generation
1const storybookRoot = require('storybook-root');2storybookRoot.watch('./storybook', () => {3  console.log('storybook config changed');4});5"scripts": {6}7const storybookRoot = require('storybook-root');8storybookRoot('./storybook');9module.exports = {10};11module.exports = {12  webpackFinal: async (config, { configType }) => {13    return config;14  },15};16module.exports = {17  webpackFinal: async (config, { configType }) => {18    return config;19  },20  managerWebpack: async (config, { configType }) => {21    return config;22  },23};24module.exports = {25  webpackFinal: async (config, { configType }) => {26    return config;27  },28  managerWebpack: async (config, { configType }) => {29    return config;30  },31  managerEntries: async (entries) => {32    return entries;33  },34};35module.exports = {36  webpackFinal: async (config, { configType }) => {37    return config;38  },39  managerWebpack: async (config, { configType }) => {40    return config;41  },42  managerEntries: async (entries) => {43    return entries;44  },45  previewEntries: async (entries) => {46    return entries;47  },48};Using AI Code Generation
1const storybookRoot = require('storybook-root');2storybookRoot.watch({3  onReady: (storybook) => {4  }5});6import { storiesOf } from '@storybook/react';7import Button from '../components/Button';8storiesOf('Button', module)9  .add('with text', () => (10    <Button onClick={action('clicked')}>Hello Button</Button>11  .add('with some emoji', () => (12    <Button onClick={action('clicked')}>😀 😎 👍 💯</Button>13  ));14import React from 'react';15import PropTypes from 'prop-types';16import './Button.css';17const Button = ({ onClick, children }) => (18  <button className="button" onClick={onClick}>19    {children}20);21Button.propTypes = {22};23Button.defaultProps = {24  onClick: () => {},25};26export default Button;27.button {28  border: none;29  border-radius: 5px;30  background-color: #333;31  color: white;32  padding: 10px;33  cursor: pointer;34}35import './button.stories';36import { storiesOf } from '@storybook/react';37import Button from '../components/Button';38storiesOf('Button', module)39  .add('with text', () => (40    <Button onClick={action('clicked')}>Hello Button</Button>41  .add('with some emoji', () => (42    <Button onClick={action('clicked')}>😀 😎 👍 💯</Button>43  ));44import React from 'react';45import PropTypes from 'prop-types';46import './Button.css';47const Button = ({ onClick, children }) => (48  <button className="button" onClick={onClick}>49    {children}50);51Button.propTypes = {52};53Button.defaultProps = {54  onClick: () => {},55};56export default Button;Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
