From 5b0f7ab78c5a918d38f5e036e2c402aab105dc43 Mon Sep 17 00:00:00 2001 From: Mark Sujew Date: Mon, 2 Sep 2024 04:43:26 +0200 Subject: [PATCH] Support file watching on virtual file systems (#4359) * Support file watching on virtual file systems * Revert some changes * Only allow URI in watcher arguments --- src/compile/build.ts | 6 +- src/completion/completer/citation.ts | 6 +- src/core/cache.ts | 38 +++++---- src/core/root.ts | 4 +- src/core/watcher.ts | 107 +++++++++++++------------ src/preview/viewer.ts | 17 ++-- src/preview/viewer/pdfviewermanager.ts | 2 +- test/units/02_core_watcher.test.ts | 42 +++++----- test/units/03_core_cache.test.ts | 32 ++++---- test/units/04_core_root.test.ts | 4 +- 10 files changed, 131 insertions(+), 127 deletions(-) diff --git a/src/compile/build.ts b/src/compile/build.ts index 76fe35629..37a8b513d 100644 --- a/src/compile/build.ts +++ b/src/compile/build.ts @@ -15,8 +15,8 @@ export { build, } -lw.watcher.src.onChange(filePath => autoBuild(filePath, 'onFileChange')) -lw.watcher.bib.onChange(filePath => autoBuild(filePath, 'onFileChange', true)) +lw.watcher.src.onChange(filePath => autoBuild(filePath.fsPath, 'onFileChange')) +lw.watcher.bib.onChange(filePath => autoBuild(filePath.fsPath, 'onFileChange', true)) /** * Triggers auto build based on file change or file save events. If the @@ -420,7 +420,7 @@ async function afterSuccessfulBuilt(lastStep: Step, skipped: boolean) { if (!lastStep.isExternal && skipped) { return } - lw.viewer.refresh(lw.file.getPdfPath(lastStep.rootFile)) + lw.viewer.refresh(vscode.Uri.file(lw.file.getPdfPath(lastStep.rootFile))) lw.completion.reference.setNumbersFromAuxFile(lastStep.rootFile) await lw.cache.loadFlsFile(lastStep.rootFile ?? '') const configuration = vscode.workspace.getConfiguration('latex-workshop', vscode.Uri.file(lastStep.rootFile)) diff --git a/src/completion/completer/citation.ts b/src/completion/completer/citation.ts index cef247709..050b564a5 100644 --- a/src/completion/completer/citation.ts +++ b/src/completion/completer/citation.ts @@ -22,9 +22,9 @@ const data = { bibEntries: new Map() } -lw.watcher.bib.onCreate(filePath => parseBibFile(filePath)) -lw.watcher.bib.onChange(filePath => parseBibFile(filePath)) -lw.watcher.bib.onDelete(filePath => removeEntriesInFile(filePath)) +lw.watcher.bib.onCreate(uri => parseBibFile(uri.fsPath)) +lw.watcher.bib.onChange(uri => parseBibFile(uri.fsPath)) +lw.watcher.bib.onDelete(uri => removeEntriesInFile(uri.fsPath)) /** * Read the value `intellisense.citation.format` diff --git a/src/core/cache.ts b/src/core/cache.ts index 0abb59de8..6c7d5fc07 100644 --- a/src/core/cache.ts +++ b/src/core/cache.ts @@ -45,17 +45,17 @@ export const cache = { } // Listener for file changes: refreshes the cache if the file can be cached. -lw.watcher.src.onChange((filePath: string) => { - if (canCache(filePath)) { - void refreshCache(filePath) +lw.watcher.src.onChange(uri => { + if (canCache(uri.fsPath)) { + void refreshCache(uri.fsPath) } }) // Listener for file deletions: removes the file from the cache if it exists. -lw.watcher.src.onDelete((filePath: string) => { - if (get(filePath) !== undefined) { - caches.delete(filePath) - logger.log(`Removed ${filePath} .`) +lw.watcher.src.onDelete(uri => { + if (get(uri.fsPath) !== undefined) { + caches.delete(uri.fsPath) + logger.log(`Removed ${uri.fsPath} .`) } }) @@ -114,9 +114,10 @@ function add(filePath: string) { logger.log(`Ignored ${filePath} .`) return } - if (!lw.watcher.src.has(filePath)) { + const uri = vscode.Uri.file(filePath) + if (!lw.watcher.src.has(uri)) { logger.log(`Adding ${filePath} .`) - lw.watcher.src.add(filePath) + lw.watcher.src.add(uri) } } @@ -393,7 +394,7 @@ async function updateChildrenInput(fileCache: FileCache, rootPath: string) { }) logger.log(`Input ${result.path} from ${fileCache.filePath} .`) - if (lw.watcher.src.has(result.path)) { + if (lw.watcher.src.has(vscode.Uri.file(result.path))) { continue } add(result.path) @@ -440,7 +441,7 @@ async function updateChildrenXr(fileCache: FileCache, rootPath: string) { logger.log(`External document ${externalPath} from ${fileCache.filePath} .` + (result[1] ? ` Prefix is ${result[1]}`: '')) } - if (lw.watcher.src.has(externalPath)) { + if (lw.watcher.src.has(vscode.Uri.file(externalPath))) { continue } add(externalPath) @@ -506,8 +507,9 @@ function updateBibfiles(fileCache: FileCache) { } fileCache.bibfiles.add(bibPath) logger.log(`Bib ${bibPath} from ${fileCache.filePath} .`) - if (!lw.watcher.bib.has(bibPath)) { - lw.watcher.bib.add(bibPath) + const bibUri = vscode.Uri.file(bibPath) + if (!lw.watcher.bib.has(bibUri)) { + lw.watcher.bib.add(bibUri) } } } @@ -544,13 +546,14 @@ async function loadFlsFile(filePath: string): Promise { const ioFiles = parseFlsContent(await lw.file.read(flsPath) ?? '', rootDir) for (const inputFile of ioFiles.input) { + const inputUri = vscode.Uri.file(inputFile) // Drop files that are also listed as OUTPUT or should be ignored if (ioFiles.output.includes(inputFile) || isExcluded(inputFile) || !await lw.file.exists(inputFile)) { continue } - if (inputFile === filePath || lw.watcher.src.has(inputFile)) { + if (inputFile === filePath || lw.watcher.src.has(inputUri)) { // Drop the current rootFile often listed as INPUT // Drop any file that is already watched as it is handled by // onWatchedFileChange. @@ -576,7 +579,7 @@ async function loadFlsFile(filePath: string): Promise { } else { logger.log(`Cache not finished on ${filePath} when parsing fls.`) } - } else if (!lw.watcher.src.has(inputFile) && !['.aux', '.out'].includes(inputExt)) { + } else if (!lw.watcher.src.has(inputUri) && !['.aux', '.out'].includes(inputExt)) { // Watch non-tex files. aux and out are excluded because they are auto-generated during the building process add(inputFile) } @@ -672,8 +675,9 @@ async function parseAuxFile(filePath: string, srcDir: string) { get(lw.root.file.path)?.bibfiles.add(bibPath) logger.log(`Found .bib ${bibPath} from .aux ${filePath} .`) } - if (!lw.watcher.bib.has(bibPath)) { - lw.watcher.bib.add(bibPath) + const bibUri = vscode.Uri.file(bibPath) + if (!lw.watcher.bib.has(bibUri)) { + lw.watcher.bib.add(bibUri) } } } diff --git a/src/core/root.ts b/src/core/root.ts index d13da824a..67f088136 100644 --- a/src/core/root.ts +++ b/src/core/root.ts @@ -23,8 +23,8 @@ export const root = { getWorkspace } -lw.watcher.src.onDelete(filePath => { - if (filePath !== root.file.path) { +lw.watcher.src.onDelete(uri => { + if (uri.fsPath !== root.file.path) { return } root.file = { path: undefined, langId: undefined } diff --git a/src/core/watcher.ts b/src/core/watcher.ts index 1006a8cfb..3febf63ef 100644 --- a/src/core/watcher.ts +++ b/src/core/watcher.ts @@ -20,27 +20,27 @@ class Watcher { private get onCreateHandlers() { return this._onCreateHandlers } - private readonly _onCreateHandlers: Set<(filePath: string) => void> = new Set() + private readonly _onCreateHandlers: Set<(uri: vscode.Uri) => void> = new Set() /** * Set of handlers to be called when a file is changed. */ private get onChangeHandlers() { return this._onChangeHandlers } - private readonly _onChangeHandlers: Set<(filePath: string) => void> = new Set() + private readonly _onChangeHandlers: Set<(uri: vscode.Uri) => void> = new Set() /** * Set of handlers to be called when a file is deleted. */ private get onDeleteHandlers() { return this._onDeleteHandlers } - private readonly _onDeleteHandlers: Set<(filePath: string) => void> = new Set() + private readonly _onDeleteHandlers: Set<(uri: vscode.Uri) => void> = new Set() /** * Map of file paths to polling information. This may be of particular use * when large binary files are progressively write to disk, and multiple * 'change' events are therefore emitted in a short period of time. */ - private readonly polling: {[filePath: string]: {time: number, size: number}} = {} + private readonly polling: {[uriString: string]: {time: number, size: number}} = {} /** * Creates a new Watcher instance. @@ -52,27 +52,27 @@ class Watcher { /** * Adds a handler for file creation events. * - * @param {(filePath: string) => void} handler - The handler function. + * @param {(uri: vscode.Uri) => void} handler - The handler function. */ - onCreate(handler: (filePath: string) => void) { + onCreate(handler: (uri: vscode.Uri) => void) { this.onCreateHandlers.add(handler) } /** * Adds a handler for file change events. * - * @param {(filePath: string) => void} handler - The handler function. + * @param {(uri: vscode.Uri) => void} handler - The handler function. */ - onChange(handler: (filePath: string) => void) { + onChange(handler: (uri: vscode.Uri) => void) { this.onChangeHandlers.add(handler) } /** * Adds a handler for file deletion events. * - * @param {(filePath: string) => void} handler - The handler function. + * @param {(uri: vscode.Uri) => void} handler - The handler function. */ - onDelete(handler: (filePath: string) => void) { + onDelete(handler: (uri: vscode.Uri) => void) { this.onDeleteHandlers.add(handler) } @@ -108,7 +108,7 @@ class Watcher { if (!lw.file.hasBinaryExt(path.extname(uri.fsPath))) { this.handleNonBinaryFileChange(event, uri) - } else if (!this.polling[uri.fsPath]) { + } else if (!this.polling[uri.toString()]) { await this.initiatePolling(uri) } } @@ -120,10 +120,10 @@ class Watcher { * @param {vscode.Uri} uri - The URI of the changed file. */ private handleNonBinaryFileChange(event: string, uri: vscode.Uri): void { - const filePath = uri.fsPath - logger.log(`"${event}" emitted on ${filePath}.`) - this.onChangeHandlers.forEach(handler => handler(filePath)) - lw.event.fire(lw.event.FileChanged, filePath) + const uriString = uri.toString() + logger.log(`"${event}" emitted on ${uriString}.`) + this.onChangeHandlers.forEach(handler => handler(uri)) + lw.event.fire(lw.event.FileChanged, uriString) } /** @@ -138,14 +138,14 @@ class Watcher { * @param {vscode.Uri} uri - The URI of the changed file. */ private async initiatePolling(uri: vscode.Uri): Promise { - const filePath = uri.fsPath + const uriString = uri.toString() const firstChangeTime = Date.now() - const size = (await lw.external.stat(vscode.Uri.file(filePath))).size + const size = (await lw.external.stat(uri)).size - this.polling[filePath] = { size, time: firstChangeTime } + this.polling[uriString] = { size, time: firstChangeTime } const pollingInterval = setInterval(async () => { - await this.handlePolling(filePath, size, firstChangeTime, pollingInterval) + await this.handlePolling(uri, size, firstChangeTime, pollingInterval) }, vscode.workspace.getConfiguration('latex-workshop').get('latex.watch.pdf.delay') as number) } @@ -159,32 +159,33 @@ class Watcher { * specified time (200 milliseconds), it is considered a valid change, and * the appropriate handlers are triggered. * - * @param {string} filePath - The path of the changed file. + * @param {uri: vscode.Uri} uri - The uri of the changed file. * @param {number} size - The size of the file. * @param {number} firstChangeTime - The timestamp of the first change. * @param {NodeJS.Timeout} interval - The polling interval. */ - private async handlePolling(filePath: string, size: number, firstChangeTime: number, interval: NodeJS.Timeout): Promise { - if (!await lw.file.exists(filePath)) { + private async handlePolling(uri: vscode.Uri, size: number, firstChangeTime: number, interval: NodeJS.Timeout): Promise { + const uriString = uri.toString() + if (!await lw.file.exists(uri)) { clearInterval(interval) - delete this.polling[filePath] + delete this.polling[uriString] return } - const currentSize = (await lw.external.stat(vscode.Uri.file(filePath))).size + const currentSize = (await lw.external.stat(uri)).size if (currentSize !== size) { - this.polling[filePath].size = currentSize - this.polling[filePath].time = Date.now() + this.polling[uriString].size = currentSize + this.polling[uriString].time = Date.now() return } - if (Date.now() - this.polling[filePath].time >= 200) { - logger.log(`"change" emitted on ${filePath} after polling for ${Date.now() - firstChangeTime} ms.`) + if (Date.now() - this.polling[uriString].time >= 200) { + logger.log(`"change" emitted on ${uriString} after polling for ${Date.now() - firstChangeTime} ms.`) clearInterval(interval) - delete this.polling[filePath] - this.onChangeHandlers.forEach(handler => handler(filePath)) - lw.event.fire(lw.event.FileChanged, filePath) + delete this.polling[uriString] + this.onChangeHandlers.forEach(handler => handler(uri)) + lw.event.fire(lw.event.FileChanged, uriString) } } @@ -202,24 +203,24 @@ class Watcher { return } - const filePath = uri.fsPath - logger.log(`"delete" emitted on ${filePath}.`) + const uriString = uri.toString() + logger.log(`"delete" emitted on ${uriString}.`) return new Promise(resolve => { setTimeout(async () => { - if (await lw.file.exists(filePath)) { - logger.log(`File deleted and re-created: ${filePath} .`) + if (await lw.file.exists(uri)) { + logger.log(`File deleted and re-created: ${uriString} .`) resolve() return } - logger.log(`File deletion confirmed: ${filePath} .`) - this.onDeleteHandlers.forEach(handler => handler(filePath)) + logger.log(`File deletion confirmed: ${uriString} .`) + this.onDeleteHandlers.forEach(handler => handler(uri)) watcherInfo.files.delete(fileName) if (watcherInfo.files.size === 0) { this.disposeWatcher(folder) } - lw.event.fire(lw.event.FileRemoved, filePath) + lw.event.fire(lw.event.FileRemoved, uriString) resolve() }, vscode.workspace.getConfiguration('latex-workshop').get('latex.watch.delay') as number) }) @@ -246,43 +247,43 @@ class Watcher { * the set of files being watched. If a watcher already exists, the file is * simply added to the set of files being watched by the existing watcher. * - * @param {string} filePath - The path of the file to watch. + * @param {vscode.Uri} uri - The uri of the file to watch. */ - add(filePath: string) { - const fileName = path.basename(filePath) - const folder = path.dirname(filePath) + add(uri: vscode.Uri) { + const fileName = path.basename(uri.fsPath) + const folder = path.dirname(uri.fsPath) if (!this.watchers[folder]) { this.watchers[folder] = { watcher: this.createWatcher(new vscode.RelativePattern(folder, `*${this.fileExt}`)), files: new Set([fileName]) } - this.onCreateHandlers.forEach(handler => handler(filePath)) - logger.log(`Watched ${filePath} with a new ${this.fileExt} watcher on ${folder} .`) + this.onCreateHandlers.forEach(handler => handler(uri)) + logger.log(`Watched ${uri.toString()} with a new ${this.fileExt} watcher on ${folder} .`) } else { this.watchers[folder].files.add(fileName) - this.onCreateHandlers.forEach(handler => handler(filePath)) - logger.log(`Watched ${filePath} by the ${this.fileExt} watcher.`) + this.onCreateHandlers.forEach(handler => handler(uri)) + logger.log(`Watched ${uri.toString()} by the ${this.fileExt} watcher.`) } - lw.event.fire(lw.event.FileWatched, filePath) + lw.event.fire(lw.event.FileWatched, uri.toString()) } /** * Removes a file from being watched. * - * @param {string} filePath - The path of the file to stop watching. + * @param {vscode.Uri} uri - The uri of the file to stop watching. */ - remove(filePath: string) { - this.watchers[path.dirname(filePath)]?.files.delete(path.basename(filePath)) + remove(uri: vscode.Uri) { + this.watchers[path.dirname(uri.fsPath)]?.files.delete(path.basename(uri.fsPath)) } /** * Checks if a file is currently being watched. * - * @param {string} filePath - The path of the file to check. + * @param {vscode.Uri} uri - The uri of the file to check. * @returns {boolean} - Indicates whether the file is being watched. */ - has(filePath: string): boolean { - return this.watchers[path.dirname(filePath)]?.files.has(path.basename(filePath)) + has(uri: vscode.Uri): boolean { + return this.watchers[path.dirname(uri.fsPath)]?.files.has(path.basename(uri.fsPath)) } /** diff --git a/src/preview/viewer.ts b/src/preview/viewer.ts index 6bad370ef..1a05de76d 100644 --- a/src/preview/viewer.ts +++ b/src/preview/viewer.ts @@ -28,9 +28,9 @@ export { export { serializer } from './viewer/pdfviewerpanel' export { hook } from './viewer/pdfviewerhook' -lw.watcher.pdf.onChange(pdfPath => { - if (lw.compile.compiledPDFWriting === 0 || path.relative(lw.compile.compiledPDFPath, pdfPath) !== '') { - refresh(pdfPath) +lw.watcher.pdf.onChange(pdfUri => { + if (lw.compile.compiledPDFWriting === 0 || path.relative(lw.compile.compiledPDFPath, pdfUri.fsPath) !== '') { + refresh(pdfUri) } }) lw.onConfigChange(['view.pdf.invert', 'view.pdf.invertMode', 'view.pdf.color', 'view.pdf.internal'], () => { @@ -51,9 +51,8 @@ function reload(): void { * @param pdfFile The path of a PDF file. If `pdfFile` is `undefined`, * refreshes all the PDF viewers. */ -function refresh(pdfFile?: string): void { - logger.log(`Call refreshExistingViewer: ${JSON.stringify(pdfFile)} .`) - const pdfUri = pdfFile ? vscode.Uri.file(pdfFile) : undefined +function refresh(pdfUri?: vscode.Uri): void { + logger.log(`Call refreshExistingViewer: ${pdfUri ?? 'undefined'} .`) if (pdfUri === undefined) { manager.getClients()?.forEach(client => { client.send({type: 'refresh'}) @@ -62,10 +61,10 @@ function refresh(pdfFile?: string): void { } const clientSet = manager.getClients(pdfUri) if (!clientSet) { - logger.log(`Not found PDF viewers to refresh: ${pdfFile}`) + logger.log(`Not found PDF viewers to refresh: ${pdfUri}`) return } - logger.log(`Refresh PDF viewer: ${pdfFile}`) + logger.log(`Refresh PDF viewer: ${pdfUri}`) clientSet.forEach(client => { client.send({type: 'refresh'}) }) @@ -113,7 +112,7 @@ async function viewInBrowser(pdfFile: string): Promise { } const pdfUri = vscode.Uri.file(pdfFile) manager.create(pdfUri) - lw.watcher.pdf.add(pdfUri.fsPath) + lw.watcher.pdf.add(pdfUri) try { logger.log(`Serving PDF file at ${url}`) await vscode.env.openExternal(vscode.Uri.parse(url, true)) diff --git a/src/preview/viewer/pdfviewermanager.ts b/src/preview/viewer/pdfviewermanager.ts index 3d912c3a6..f01910fc2 100644 --- a/src/preview/viewer/pdfviewermanager.ts +++ b/src/preview/viewer/pdfviewermanager.ts @@ -49,7 +49,7 @@ function getPanels(pdfUri: vscode.Uri): Set | undefined { function insert(pdfPanel: PdfViewerPanel): PdfViewerPanel | undefined { const pdfUri = pdfPanel.pdfUri - lw.watcher.pdf.add(pdfUri.fsPath) + lw.watcher.pdf.add(pdfUri) create(pdfUri) const panelSet = getPanels(pdfUri) if (!panelSet) { diff --git a/test/units/02_core_watcher.test.ts b/test/units/02_core_watcher.test.ts index f85704bed..c3c9a0c9e 100644 --- a/test/units/02_core_watcher.test.ts +++ b/test/units/02_core_watcher.test.ts @@ -13,9 +13,9 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { let _watchersSpy: sinon.SinonSpy const getWatchers = () => _watchersSpy.call(lw.watcher.src) as {[folder: string]: {watcher: vscode.FileSystemWatcher, files: Set}} let _onChangeHandlersSpy: sinon.SinonSpy - const getOnChangeHandlers = () => _onChangeHandlersSpy.call(lw.watcher.src) as Set<(filePath: string) => void> + const getOnChangeHandlers = () => _onChangeHandlersSpy.call(lw.watcher.src) as Set<(uri: vscode.Uri) => void> let _onDeleteHandlersSpy: sinon.SinonSpy - const getOnDeleteHandlers = () => _onDeleteHandlersSpy.call(lw.watcher.src) as Set<(filePath: string) => void> + const getOnDeleteHandlers = () => _onDeleteHandlersSpy.call(lw.watcher.src) as Set<(uri: vscode.Uri) => void> before(() => { mock.object(lw, 'file', 'watcher') @@ -54,7 +54,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { const texPath = get.path(fixture, 'main.tex') const spy = sinon.spy(lw.watcher.src as any, 'createWatcher') - lw.watcher.src.add(texPath) + lw.watcher.src.add(vscode.Uri.file(texPath)) assert.ok(spy.called) assert.ok(Object.keys(getWatchers()).includes(rootDir)) assert.ok(getWatchers()[rootDir].files.has('main.tex')) @@ -64,8 +64,8 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { const rootDir = get.path(fixture) const texPath = get.path(fixture, 'main.tex') - lw.watcher.src.add(texPath) - lw.watcher.src.add(get.path(fixture, 'another.tex')) + lw.watcher.src.add(vscode.Uri.file(texPath)) + lw.watcher.src.add(vscode.Uri.file(get.path(fixture, 'another.tex'))) assert.listStrictEqual(Object.keys(getWatchers()), [ rootDir ]) assert.ok(getWatchers()[rootDir].files.has('another.tex')) }) @@ -80,16 +80,16 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { const rootDir = get.path(fixture) const texPath = get.path(fixture, 'main.tex') - lw.watcher.src.add(texPath) + lw.watcher.src.add(vscode.Uri.file(texPath)) assert.ok(getWatchers()[rootDir].files.has('main.tex')) - lw.watcher.src.remove(texPath) + lw.watcher.src.remove(vscode.Uri.file(texPath)) assert.ok(!getWatchers()[rootDir].files.has('main.tex')) }) it('should not throw an error if the file is not being watched', () => { const texPath = get.path(fixture, 'main.tex') - lw.watcher.src.remove(texPath) + lw.watcher.src.remove(vscode.Uri.file(texPath)) assert.ok(true) }) }) @@ -103,7 +103,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { const rootDir = get.path(fixture) const texPath = get.path(fixture, 'main.tex') - lw.watcher.src.add(texPath) + lw.watcher.src.add(vscode.Uri.file(texPath)) assert.ok(getWatchers()[rootDir].files.has('main.tex')) }) @@ -111,7 +111,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { const rootDir = get.path(fixture) const texPath = get.path(fixture, 'main.tex') - lw.watcher.src.add(texPath) + lw.watcher.src.add(vscode.Uri.file(texPath)) assert.ok(!getWatchers()[rootDir].files.has('another.tex')) }) }) @@ -125,7 +125,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { const rootDir = get.path(fixture) const texPath = get.path(fixture, 'main.tex') - lw.watcher.src.add(texPath) + lw.watcher.src.add(vscode.Uri.file(texPath)) const spy = sinon.spy(getWatchers()[rootDir].watcher, 'dispose') lw.watcher.src.reset() spy.restore() @@ -136,7 +136,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { describe('lw.watcher.src.onDidChange', () => { const stub = sinon.stub() - const handler = (filePath: string) => { stub(filePath) } + const handler = (filePath: vscode.Uri) => { stub(filePath.fsPath) } beforeEach(() => { stub.reset() @@ -151,7 +151,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { it('should call onChangeHandlers when creating watched file', async () => { const texPath = get.path(fixture, 'main.tex') - lw.watcher.src.add(texPath) + lw.watcher.src.add(vscode.Uri.file(texPath)) await callOnDidChange('create', vscode.Uri.file(texPath)) assert.strictEqual(stub.callCount, 1) assert.listStrictEqual(stub.getCall(0).args, [ texPath ]) @@ -160,7 +160,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { it('should call onChangeHandlers when changing watched file', async () => { const texPath = get.path(fixture, 'main.tex') - lw.watcher.src.add(texPath) + lw.watcher.src.add(vscode.Uri.file(texPath)) await callOnDidChange('change', vscode.Uri.file(texPath)) assert.strictEqual(stub.callCount, 1) assert.listStrictEqual(stub.getCall(0).args, [ texPath ]) @@ -169,7 +169,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { it('should not call onChangeHandlers when creating non-watched file', async () => { const texPath = get.path(fixture, 'main.tex') - lw.watcher.src.add(texPath) + lw.watcher.src.add(vscode.Uri.file(texPath)) await callOnDidChange('create', vscode.Uri.file(get.path(fixture, 'another.tex'))) assert.strictEqual(stub.callCount, 0) }) @@ -177,7 +177,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { it('should not call onChangeHandlers when changing non-watched file', async () => { const texPath = get.path(fixture, 'main.tex') - lw.watcher.src.add(texPath) + lw.watcher.src.add(vscode.Uri.file(texPath)) await callOnDidChange('change', vscode.Uri.file(get.path(fixture, 'another.tex'))) assert.strictEqual(stub.callCount, 0) }) @@ -186,7 +186,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { this.slow(1050) const binPath = get.path(fixture, 'main.bin') - lw.watcher.src.add(binPath) + lw.watcher.src.add(vscode.Uri.file(binPath)) await callOnDidChange('change', vscode.Uri.file(binPath)) await callOnDidChange('change', vscode.Uri.file(binPath)) await sleep(500) @@ -197,7 +197,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { this.slow(2050) const binPath = get.path(fixture, 'main.bin') - lw.watcher.src.add(binPath) + lw.watcher.src.add(vscode.Uri.file(binPath)) await callOnDidChange('change', vscode.Uri.file(binPath)) await sleep(500) await callOnDidChange('change', vscode.Uri.file(binPath)) @@ -208,7 +208,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { describe('lw.watcher.src.onDidDelete', () => { const stub = sinon.stub() - const handler = (filePath: string) => { stub(filePath) } + const handler = (filePath: vscode.Uri) => { stub(filePath.fsPath) } beforeEach(async () => { stub.reset() @@ -225,7 +225,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { this.slow(250) const texPath = get.path(fixture, 'main.tex') - lw.watcher.src.add(texPath) + lw.watcher.src.add(vscode.Uri.file(texPath)) await callOnDidDelete(vscode.Uri.file(texPath)) assert.strictEqual(stub.callCount, 1) assert.listStrictEqual(stub.getCall(0).args, [ texPath ]) @@ -235,7 +235,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { this.slow(250) const binPath = get.path(fixture, 'main.bin') - lw.watcher.src.add(binPath) + lw.watcher.src.add(vscode.Uri.file(binPath)) await callOnDidDelete(vscode.Uri.file(binPath)) assert.strictEqual(stub.callCount, 0) }) diff --git a/test/units/03_core_cache.test.ts b/test/units/03_core_cache.test.ts index 2ccfeae8d..cf908a2d0 100644 --- a/test/units/03_core_cache.test.ts +++ b/test/units/03_core_cache.test.ts @@ -109,14 +109,14 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { const texPath = get.path(fixture, 'main.tex') lw.cache.add(texPath) - assert.ok(lw.watcher.src.has(texPath)) + assert.ok(lw.watcher.src.has(vscode.Uri.file(texPath))) }) it('should ignore excluded files', () => { const bblPath = get.path(fixture, 'main.bbl') lw.cache.add(bblPath) - assert.ok(!lw.watcher.src.has(bblPath)) + assert.ok(!lw.watcher.src.has(vscode.Uri.file(bblPath))) }) it('should add a file to watcher but not cache it', () => { @@ -194,13 +194,13 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { const bibPath = get.path(fixture, 'main.bib') const pdfPath = get.path(fixture, 'main.pdf') - lw.watcher.src.add(texPath) - lw.watcher.bib.add(bibPath) - lw.watcher.pdf.add(pdfPath) + lw.watcher.src.add(vscode.Uri.file(texPath)) + lw.watcher.bib.add(vscode.Uri.file(bibPath)) + lw.watcher.pdf.add(vscode.Uri.file(pdfPath)) lw.cache.reset() - assert.ok(!lw.watcher.src.has(texPath)) - assert.ok(!lw.watcher.bib.has(bibPath)) - assert.ok(lw.watcher.pdf.has(pdfPath)) + assert.ok(!lw.watcher.src.has(vscode.Uri.file(texPath))) + assert.ok(!lw.watcher.bib.has(vscode.Uri.file(bibPath))) + assert.ok(lw.watcher.pdf.has(vscode.Uri.file(pdfPath))) }) it('should reset the cache', async () => { @@ -447,7 +447,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { lw.cache.add(toParse) await lw.cache.refreshCache(toParse) - assert.ok(lw.watcher.src.has(texPath)) + assert.ok(lw.watcher.src.has(vscode.Uri.file(texPath))) }) it('should add two children if there are two inputs', async () => { @@ -583,7 +583,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { lw.cache.add(toParse) await lw.cache.refreshCache(toParse) - assert.ok(lw.watcher.src.has(texPath)) + assert.ok(lw.watcher.src.has(vscode.Uri.file(texPath))) }) it('should add a child with prefix', async () => { @@ -665,7 +665,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { lw.cache.add(toParse) await lw.cache.refreshCache(toParse) - assert.ok(lw.watcher.bib.has(bibPath)) + assert.ok(lw.watcher.bib.has(vscode.Uri.file(bibPath))) }) }) @@ -738,7 +738,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { const toParse = get.path(fixture, 'load_fls_file', 'include_main.tex') await lw.cache.loadFlsFile(toParse) - assert.ok(lw.watcher.src.has(texPath)) + assert.ok(lw.watcher.src.has(vscode.Uri.file(texPath))) }) it('should watch added non-.tex files', async () => { @@ -746,14 +746,14 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { const toParse = get.path(fixture, 'load_fls_file', 'non_tex_input.tex') await lw.cache.loadFlsFile(toParse) - assert.ok(lw.watcher.src.has(pdfPath)) + assert.ok(lw.watcher.src.has(vscode.Uri.file(pdfPath))) }) it('should watch added non-.tex files, except for aux or out files', async () => { const toParse = get.path(fixture, 'load_fls_file', 'aux_out_input.tex') await lw.cache.loadFlsFile(toParse) - assert.ok(!lw.watcher.src.has(get.path(fixture, 'load_fls_file', 'main.aux'))) - assert.ok(!lw.watcher.src.has(get.path(fixture, 'load_fls_file', 'main.out'))) + assert.ok(!lw.watcher.src.has(vscode.Uri.file(get.path(fixture, 'load_fls_file', 'main.aux')))) + assert.ok(!lw.watcher.src.has(vscode.Uri.file(get.path(fixture, 'load_fls_file', 'main.out')))) }) }) @@ -788,7 +788,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { set.root(fixture, 'load_aux_file', 'main.tex') await lw.cache.refreshCache(toParse) await lw.cache.loadFlsFile(toParse) - assert.ok(lw.watcher.bib.has(get.path(fixture, 'load_aux_file', 'main.bib'))) + assert.ok(lw.watcher.bib.has(vscode.Uri.file(get.path(fixture, 'load_aux_file', 'main.bib')))) }) }) diff --git a/test/units/04_core_root.test.ts b/test/units/04_core_root.test.ts index 2542632db..3abf24640 100644 --- a/test/units/04_core_root.test.ts +++ b/test/units/04_core_root.test.ts @@ -29,7 +29,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { const texPath = get.path(fixture, 'another.tex') lw.root.file.path = texPath - lw.watcher.src.add(texPath) + lw.watcher.src.add(vscode.Uri.file(texPath)) assert.notHasLog('Current workspace folders: ') const onDidDeleteSpy = sinon.spy(lw.watcher.src as any, 'onDidDelete') @@ -528,7 +528,7 @@ describe(path.basename(__filename).split('.')[0] + ':', () => { stub.restore() cacheSpy1.restore() - assert.ok(lw.watcher.src.has(texPath)) + assert.ok(lw.watcher.src.has(vscode.Uri.file(texPath))) assert.strictEqual(cacheSpy1.callCount, 1) await lw.cache.wait(texPath)