mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
The logic is pretty complex and I don't want to take the time to integrate @atom/notify with it. I left a bunch of stuff commented out in this commit just in case these changes break the build. I'll do another pass to delete commented code once we go green.
186 lines
6.0 KiB
JavaScript
186 lines
6.0 KiB
JavaScript
/** @babel */
|
|
|
|
import temp from 'temp'
|
|
import fs from 'fs-plus'
|
|
import path from 'path'
|
|
import { promisify } from 'util'
|
|
|
|
import { CompositeDisposable } from 'event-kit'
|
|
import { PathWatcherManager } from '../src/path-watcher'
|
|
|
|
temp.track()
|
|
|
|
const writeFile = promisify(fs.writeFile)
|
|
const mkdir = promisify(fs.mkdir)
|
|
const appendFile = promisify(fs.appendFile)
|
|
const realpath = promisify(fs.realpath)
|
|
|
|
const tempMkdir = promisify(temp.mkdir)
|
|
|
|
describe('PathWatcherManager', function () {
|
|
let subs
|
|
|
|
beforeEach(function () {
|
|
subs = new CompositeDisposable()
|
|
})
|
|
|
|
afterEach(async function () {
|
|
subs.dispose()
|
|
})
|
|
|
|
function waitForChanges (watcher, ...fileNames) {
|
|
const waiting = new Set(fileNames)
|
|
let fired = false
|
|
const relevantEvents = []
|
|
|
|
return new Promise(resolve => {
|
|
const sub = watcher.onDidChange(events => {
|
|
for (const event of events) {
|
|
if (waiting.delete(event.path)) {
|
|
relevantEvents.push(event)
|
|
}
|
|
}
|
|
|
|
if (!fired && waiting.size === 0) {
|
|
fired = true
|
|
resolve(relevantEvents)
|
|
sub.dispose()
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
describe('in "native" mode', () => {
|
|
let manager
|
|
|
|
beforeEach(function () {
|
|
manager = new PathWatcherManager('native')
|
|
})
|
|
|
|
afterEach(async function () {
|
|
await manager.stopAllWatchers()
|
|
})
|
|
|
|
describe('watchPath()', function () {
|
|
it('resolves the returned promise when the watcher begins listening', async function () {
|
|
const rootDir = await tempMkdir('atom-fsmanager-test-')
|
|
|
|
const watcher = await manager.watchPath(rootDir, {}, () => {})
|
|
expect(watcher.constructor.name).toBe('PathWatcher')
|
|
})
|
|
|
|
it('reuses an existing native watcher and resolves getStartPromise immediately if attached to a running watcher', async function () {
|
|
const rootDir = await tempMkdir('atom-fsmanager-test-')
|
|
|
|
const watcher0 = await manager.watchPath(rootDir, {}, () => {})
|
|
const watcher1 = await manager.watchPath(rootDir, {}, () => {})
|
|
|
|
expect(watcher0.native).toBe(watcher1.native)
|
|
})
|
|
|
|
it("reuses existing native watchers even while they're still starting", async function () {
|
|
const rootDir = await tempMkdir('atom-fsmanager-test-')
|
|
|
|
const [watcher0, watcher1] = await Promise.all([
|
|
manager.watchPath(rootDir, {}, () => {}),
|
|
manager.watchPath(rootDir, {}, () => {})
|
|
])
|
|
expect(watcher0.native).toBe(watcher1.native)
|
|
})
|
|
|
|
it("doesn't attach new watchers to a native watcher that's stopping", async function () {
|
|
const rootDir = await tempMkdir('atom-fsmanager-test-')
|
|
|
|
const watcher0 = await manager.watchPath(rootDir, {}, () => {})
|
|
const native0 = watcher0.native
|
|
|
|
watcher0.dispose()
|
|
const watcher1 = await manager.watchPath(rootDir, {}, () => {})
|
|
|
|
expect(watcher1.native).not.toBe(native0)
|
|
})
|
|
|
|
it('reuses an existing native watcher on a parent directory and filters events', async function () {
|
|
const rootDir = await tempMkdir('atom-fsmanager-test-').then(realpath)
|
|
const rootFile = path.join(rootDir, 'rootfile.txt')
|
|
const subDir = path.join(rootDir, 'subdir')
|
|
const subFile = path.join(subDir, 'subfile.txt')
|
|
|
|
await mkdir(subDir)
|
|
|
|
// Keep the watchers alive with an undisposed subscription
|
|
const rootWatcher = await manager.watchPath(rootDir, {}, () => {})
|
|
const childWatcher = await manager.watchPath(subDir, {}, () => {})
|
|
|
|
expect(rootWatcher.native).toBe(childWatcher.native)
|
|
expect(rootWatcher.native.isRunning()).toBe(true)
|
|
|
|
const firstChanges = Promise.all([
|
|
waitForChanges(rootWatcher, subFile),
|
|
waitForChanges(childWatcher, subFile)
|
|
])
|
|
await writeFile(subFile, 'subfile\n', { encoding: 'utf8' })
|
|
await firstChanges
|
|
|
|
const nextRootEvent = waitForChanges(rootWatcher, rootFile)
|
|
await writeFile(rootFile, 'rootfile\n', { encoding: 'utf8' })
|
|
await nextRootEvent
|
|
})
|
|
|
|
it('adopts existing child watchers and filters events appropriately to them', async function () {
|
|
const parentDir = await tempMkdir('atom-fsmanager-test-')
|
|
.then(realpath)
|
|
|
|
// Create the directory tree
|
|
const rootFile = path.join(parentDir, 'rootfile.txt')
|
|
const subDir0 = path.join(parentDir, 'subdir0')
|
|
const subFile0 = path.join(subDir0, 'subfile0.txt')
|
|
const subDir1 = path.join(parentDir, 'subdir1')
|
|
const subFile1 = path.join(subDir1, 'subfile1.txt')
|
|
|
|
await mkdir(subDir0)
|
|
await mkdir(subDir1)
|
|
await Promise.all([
|
|
writeFile(rootFile, 'rootfile\n', { encoding: 'utf8' }),
|
|
writeFile(subFile0, 'subfile 0\n', { encoding: 'utf8' }),
|
|
writeFile(subFile1, 'subfile 1\n', { encoding: 'utf8' })
|
|
])
|
|
|
|
// Begin the child watchers and keep them alive
|
|
const subWatcher0 = await manager.watchPath(subDir0, {}, () => {})
|
|
const subWatcherChanges0 = waitForChanges(subWatcher0, subFile0)
|
|
|
|
const subWatcher1 = await manager.watchPath(subDir1, {}, () => {})
|
|
const subWatcherChanges1 = waitForChanges(subWatcher1, subFile1)
|
|
|
|
expect(subWatcher0.native).not.toBe(subWatcher1.native)
|
|
|
|
// Create the parent watcher
|
|
const parentWatcher = await manager.watchPath(parentDir, {}, () => {})
|
|
const parentWatcherChanges = waitForChanges(
|
|
parentWatcher,
|
|
rootFile,
|
|
subFile0,
|
|
subFile1
|
|
)
|
|
|
|
expect(subWatcher0.native).toBe(parentWatcher.native)
|
|
expect(subWatcher1.native).toBe(parentWatcher.native)
|
|
|
|
// Ensure events are filtered correctly
|
|
await Promise.all([
|
|
appendFile(rootFile, 'change\n', { encoding: 'utf8' }),
|
|
appendFile(subFile0, 'change\n', { encoding: 'utf8' }),
|
|
appendFile(subFile1, 'change\n', { encoding: 'utf8' })
|
|
])
|
|
|
|
await Promise.all([
|
|
subWatcherChanges0,
|
|
subWatcherChanges1,
|
|
parentWatcherChanges
|
|
])
|
|
})
|
|
})
|
|
})
|
|
})
|