mirror of
https://github.com/atom/atom.git
synced 2026-01-25 06:48:28 -05:00
WIP work on rewatching child directories
This commit is contained in:
@@ -212,8 +212,66 @@ describe('NativeWatcherRegistry', function () {
|
||||
expect(stoppedNode).toBe(true)
|
||||
})
|
||||
|
||||
it("keeps a parent watcher that's still running")
|
||||
it('reassigns new child watchers when a parent watcher is stopped', async function () {
|
||||
const CHILD0 = new MockNative('child0')
|
||||
const CHILD1 = new MockNative('child1')
|
||||
const PARENT = new MockNative('parent')
|
||||
|
||||
it('reassigns new child watchers when a parent watcher is stopped')
|
||||
const parentDir = path.join('parent')
|
||||
const childDir0 = path.join(parentDir, 'child0')
|
||||
const childDir1 = path.join(parentDir, 'child1')
|
||||
|
||||
createNative = dir => {
|
||||
if (dir === parentDir) {
|
||||
return PARENT
|
||||
} else if (dir === childDir0) {
|
||||
return CHILD0
|
||||
} else if (dir === childDir1) {
|
||||
return CHILD1
|
||||
} else {
|
||||
throw new Error(`Unexpected directory ${dir}`)
|
||||
}
|
||||
}
|
||||
|
||||
const parentWatcher = new MockWatcher(parentDir)
|
||||
const childWatcher0 = new MockWatcher(childDir0)
|
||||
const childWatcher1 = new MockWatcher(childDir1)
|
||||
|
||||
await registry.attach(parentWatcher)
|
||||
await Promise.all([
|
||||
registry.attach(childWatcher0),
|
||||
registry.attach(childWatcher1)
|
||||
])
|
||||
|
||||
// All three watchers should share the parent watcher's native watcher.
|
||||
expect(parentWatcher.native).toBe(PARENT)
|
||||
expect(childWatcher0.native).toBe(PARENT)
|
||||
expect(childWatcher1.native).toBe(PARENT)
|
||||
|
||||
// Stopping the parent should detach and recreate the child watchers.
|
||||
// (Here, they'll be the same watcher instances used before, because of the fake createNative implementation.)
|
||||
PARENT.stop()
|
||||
|
||||
expect(childWatcher0.native).toBe(CHILD0)
|
||||
expect(childWatcher1.native).toBe(CHILD1)
|
||||
|
||||
expect(registry.tree.lookup(['parent']).when({
|
||||
parent: () => false,
|
||||
missing: () => false,
|
||||
children: () => true
|
||||
})).toBe(true)
|
||||
|
||||
expect(registry.tree.lookup(['parent', 'child0']).when({
|
||||
parent: () => true,
|
||||
missing: () => false,
|
||||
children: () => false
|
||||
})).toBe(true)
|
||||
|
||||
expect(registry.tree.lookup(['parent', 'child1']).when({
|
||||
parent: () => true,
|
||||
missing: () => false,
|
||||
children: () => false
|
||||
})).toBe(true)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -21,7 +21,7 @@ class RegistryNode {
|
||||
// exist.
|
||||
lookup (pathSegments) {
|
||||
if (pathSegments.length === 0) {
|
||||
return new ChildrenResult(this.leaves())
|
||||
return new ChildrenResult(this.leaves([]))
|
||||
}
|
||||
|
||||
const child = this.children[pathSegments[0]]
|
||||
@@ -85,13 +85,17 @@ class RegistryNode {
|
||||
return Object.keys(this.children).length === 0 ? null : this
|
||||
}
|
||||
|
||||
// Private: Discover all {RegistryWatcherNode} instances beneath this tree node.
|
||||
// Private: Discover all {RegistryWatcherNode} instances beneath this tree node and the child paths
|
||||
// that they are watching.
|
||||
//
|
||||
// Returns: A possibly empty {Array} of {RegistryWatcherNode} instances that are the descendants of this node.
|
||||
leaves () {
|
||||
// * `prefix` {Array} of intermediate path segments to prepend to the resulting child paths.
|
||||
//
|
||||
// Returns: A possibly empty {Array} of `{node, path}` objects describing {RegistryWatcherNode}
|
||||
// instances beneath this node.
|
||||
leaves (prefix) {
|
||||
const results = []
|
||||
for (const p of Object.keys(this.children)) {
|
||||
results.push(...this.children[p].leaves())
|
||||
results.push(...this.children[p].leaves(prefix + [p]))
|
||||
}
|
||||
return results
|
||||
}
|
||||
@@ -104,8 +108,11 @@ class RegistryWatcherNode {
|
||||
// Private: Allocate a new node to track a {NativeWatcher}.
|
||||
//
|
||||
// * `nativeWatcher` An existing {NativeWatcher} instance.
|
||||
constructor (nativeWatcher) {
|
||||
// * `childPaths` {Array} of child directories that are currently the responsibility of this
|
||||
// {NativeWatcher}, if any
|
||||
constructor (nativeWatcher, childPaths) {
|
||||
this.nativeWatcher = nativeWatcher
|
||||
this.childPaths = new Set(childPaths)
|
||||
}
|
||||
|
||||
// Private: Accessor for the {NativeWatcher}.
|
||||
@@ -133,9 +140,11 @@ class RegistryWatcherNode {
|
||||
|
||||
// Private: Discover this {RegistryWatcherNode} instance.
|
||||
//
|
||||
// Returns: An {Array} containing this node.
|
||||
leaves () {
|
||||
return [this]
|
||||
// * `prefix` {Array} of intermediate path segments to prepend to the resulting child paths.
|
||||
//
|
||||
// Returns: An {Array} containing a `{node, path}` object describing this node.
|
||||
leaves (prefix) {
|
||||
return [{node: this, path: prefix}]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,9 +252,9 @@ export default class NativeWatcherRegistry {
|
||||
const normalizedDirectory = await watcher.getNormalizedPathPromise()
|
||||
const pathSegments = normalizedDirectory.split(path.sep).filter(segment => segment.length > 0)
|
||||
|
||||
const attachToNew = () => {
|
||||
const attachToNew = (childPaths) => {
|
||||
const native = this.createNative(normalizedDirectory)
|
||||
const leaf = new RegistryWatcherNode(native)
|
||||
const leaf = new RegistryWatcherNode(native, childPaths)
|
||||
this.tree = this.tree.insert(pathSegments, leaf)
|
||||
|
||||
const sub = native.onWillStop(() => {
|
||||
@@ -268,7 +277,7 @@ export default class NativeWatcherRegistry {
|
||||
watcher.attachToNative(native, subpath)
|
||||
},
|
||||
children: children => {
|
||||
const newNative = attachToNew()
|
||||
const newNative = attachToNew([])
|
||||
|
||||
// One or more NativeWatchers exist on child directories of the requested path.
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
@@ -281,7 +290,7 @@ export default class NativeWatcherRegistry {
|
||||
childNative.stop()
|
||||
}
|
||||
},
|
||||
missing: attachToNew
|
||||
missing: () => attachToNew([])
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user