Multiroot tests

This commit is contained in:
James-Yu 2022-12-29 10:04:22 +08:00
parent 316280308c
commit 0f2f8e6aa4
71 changed files with 161 additions and 999 deletions

View File

@ -1,26 +0,0 @@
{
"latex-workshop.latex.recipe.default": "latexmk",
"latex-workshop.latex.tools": [
{
"name": "latexmk",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-pdf",
"-outdir=%OUTDIR%",
"-jobname=wsA",
"%DOC%"
],
"env": {}
},
{
"name": "fake",
"command": "touch",
"args": [
"%DIR%/fake.pdf"
]
}
]
}

View File

@ -1,5 +0,0 @@
\documentclass{article}
\begin{document}
empty
\end{document}

View File

@ -1,27 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
],
"settings": {
"latex-workshop.latex.recipes": [
{
"name": "fake",
"tools": [
"fake"
]
},
{
"name": "latexmk",
"tools": [
"latexmk"
]
}
],
"latex-workshop.latex.recipe.default": "fake"
}
}

View File

@ -1,3 +0,0 @@
{
"latex-workshop.latex.outDir": "./out"
}

View File

@ -1,5 +0,0 @@
\documentclass{article}
\begin{document}
empty
\end{document}

View File

@ -1,10 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
]
}

View File

@ -1,3 +0,0 @@
{
"latex-workshop.latex.build.forceRecipeUsage": true
}

View File

@ -1,6 +0,0 @@
% !TEX program = noexistprogram
\documentclass{article}
\begin{document}
empty
\end{document}

View File

@ -1,13 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
],
"settings": {
"latex-workshop.latex.build.forceRecipeUsage": false
}
}

View File

@ -1,3 +0,0 @@
{
"latex-workshop.latex.search.rootFiles.include": ["main/*.tex"]
}

View File

@ -1,5 +0,0 @@
\documentclass{article}
\begin{document}
main main main
\input{sub/s.tex}
\end{document}

View File

@ -1,5 +0,0 @@
\documentclass{article}
\begin{document}
main main main
\input{../sub/s.tex}
\end{document}

View File

@ -1 +0,0 @@
subfile

View File

@ -1,10 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
]
}

View File

@ -1,3 +0,0 @@
{
"latex-workshop.latex.search.rootFiles.exclude": ["*.tex"]
}

View File

@ -1,5 +0,0 @@
\documentclass{article}
\begin{document}
main main main
\input{sub/s.tex}
\end{document}

View File

@ -1,5 +0,0 @@
\documentclass{article}
\begin{document}
main main main
\input{../sub/s.tex}
\end{document}

View File

@ -1 +0,0 @@
subfile

View File

@ -1,10 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
]
}

View File

@ -1,4 +0,0 @@
{
"latex-workshop.latex.rootFile.useSubFile": true,
"latex-workshop.latex.autoBuild.run": "onSave"
}

View File

@ -1,6 +0,0 @@
\documentclass{article}
\usepackage{subfiles}
\begin{document}
main main main
\subfile{sub/s}
\end{document}

View File

@ -1,4 +0,0 @@
\documentclass[../A.tex]{subfiles}
\begin{document}
sub sub sub
\end{document}

View File

@ -1,14 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
],
"settings": {
"latex-workshop.latex.rootFile.useSubFile": false,
"latex-workshop.latex.autoBuild.run": "never"
}
}

View File

@ -1,4 +0,0 @@
{
"latex-workshop.latex.rootFile.useSubFile": false,
"latex-workshop.latex.autoBuild.run": "onSave"
}

View File

@ -1,6 +0,0 @@
\documentclass{article}
\usepackage{subfiles}
\begin{document}
main main main
\subfile{sub/s}
\end{document}

View File

@ -1,4 +0,0 @@
\documentclass[../A.tex]{subfiles}
\begin{document}
sub sub sub
\end{document}

View File

@ -1,14 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
],
"settings": {
"latex-workshop.latex.rootFile.useSubFile": true,
"latex-workshop.latex.autoBuild.run": "never"
}
}

View File

@ -1,4 +0,0 @@
{
"latex-workshop.latex.rootFile.useSubFile": false,
"latex-workshop.latex.rootFile.doNotPrompt": true
}

View File

@ -1,6 +0,0 @@
\documentclass{article}
\usepackage{subfiles}
\begin{document}
main main main
\subfile{sub/s}
\end{document}

View File

@ -1,4 +0,0 @@
\documentclass[../A.tex]{subfiles}
\begin{document}
sub sub sub
\end{document}

View File

@ -1,10 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
]
}

View File

@ -1,26 +0,0 @@
{
"latex-workshop.latex.recipe.default": "latexmk",
"latex-workshop.latex.tools": [
{
"name": "latexmk",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-pdf",
"-outdir=%OUTDIR%",
"-jobname=wsA",
"%DOC%"
],
"env": {}
},
{
"name": "fake",
"command": "touch",
"args": [
"%DIR%/fake.pdf"
]
}
]
}

View File

@ -1,8 +0,0 @@
\documentclass{article}
\begin{document}
\section{Section 1 A}
main
\section{Section 2 A}
main
\end{document}

View File

@ -1,5 +0,0 @@
\documentclass{article}
\begin{document}
\section{Section 1 B}
\end{document}

View File

@ -1,27 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
],
"settings": {
"latex-workshop.latex.recipes": [
{
"name": "fake",
"tools": [
"fake"
]
},
{
"name": "latexmk",
"tools": [
"latexmk"
]
}
],
"latex-workshop.latex.recipe.default": "fake"
}
}

View File

@ -1,40 +0,0 @@
{
"latex-workshop.latex.recipe.default": "latexmk A",
"latex-workshop.latex.recipes": [
{
"name": "fake",
"tools": [
"fake"
]
},
{
"name": "latexmk A",
"tools": [
"latexmk"
]
}
],
"latex-workshop.latex.tools": [
{
"name": "latexmk",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-pdf",
"-outdir=%OUTDIR%",
"-jobname=wsA",
"%DOC%"
],
"env": {}
},
{
"name": "fake",
"command": "touch",
"args": [
"%DIR%/fake.pdf"
]
}
]
}

View File

@ -1,5 +0,0 @@
\documentclass{article}
\begin{document}
empty
\end{document}

View File

@ -1,14 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
],
"settings": {
"latex-workshop.latex.recipe.default": "fake",
"latex-workshop.latex.recipes": []
}
}

View File

@ -1,40 +0,0 @@
{
"latex-workshop.latex.recipe.default": "lastUsed",
"latex-workshop.latex.recipes": [
{
"name": "fake",
"tools": [
"fake"
]
},
{
"name": "latexmk A",
"tools": [
"latexmk"
]
}
],
"latex-workshop.latex.tools": [
{
"name": "latexmk",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-pdf",
"-outdir=%OUTDIR%",
"-jobname=wsA",
"%DOC%"
],
"env": {}
},
{
"name": "fake",
"command": "touch",
"args": [
"%DIR%/fake.pdf"
]
}
]
}

View File

@ -1,5 +0,0 @@
\documentclass{article}
\begin{document}
empty
\end{document}

View File

@ -1,14 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
],
"settings": {
"latex-workshop.latex.recipe.default": "fake",
"latex-workshop.latex.recipes": []
}
}

View File

@ -1,40 +0,0 @@
{
"latex-workshop.latex.recipe.default": "lastUsed",
"latex-workshop.latex.recipes": [
{
"name": "fake",
"tools": [
"fake"
]
},
{
"name": "latexmk A",
"tools": [
"latexmk"
]
}
],
"latex-workshop.latex.tools": [
{
"name": "latexmk",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-pdf",
"-outdir=%OUTDIR%",
"-jobname=wsA",
"%DOC%"
],
"env": {}
},
{
"name": "fake",
"command": "touch",
"args": [
"%DIR%/fake.pdf"
]
}
]
}

View File

@ -1,5 +0,0 @@
\documentclass{article}
\begin{document}
empty
\end{document}

View File

@ -1,5 +0,0 @@
\documentclass{article}
\begin{document}
\section{Section 1 B}
\end{document}

View File

@ -1,14 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
],
"settings": {
"latex-workshop.latex.recipe.default": "fake",
"latex-workshop.latex.recipes": []
}
}

View File

@ -1,3 +0,0 @@
{
"latex-workshop.intellisense.citation.label": "title"
}

View File

@ -1,32 +0,0 @@
@article{art1,
title = {A fake article},
author = {Davis, J. and Jones, M.},
journal = {Journal of CI tests},
year = {2022},
description = {hintFake}
}
@book{lamport1994latex,
title = {LATEX: A Document Preparation System : User's Guide and Reference Manual},
author = {Lamport, L. and Bibby, D. and Pearson Education},
isbn = {9780201529838},
lccn = {93039691},
series = {Addison-Wesley Series on Tools},
url = {https://books.google.ch/books?id=khVUAAAAMAAJ},
year = {1994},
publisher = {Addison-Wesley},
description = {hintLaTex}
}
@book{MR1241645,
author = {Rubinstein, Reuven Y. and Shapiro, Alexander},
title = {Discrete event systems},
series = {Wiley Series in Probability and Mathematical Statistics:
Probability and Mathematical Statistics},
note = {Sensitivity analysis and stochastic optimization by the score
function method},
publisher = {John Wiley \& Sons Ltd.},
address = {Chichester},
year = 1993,
description = {hintRubi}
}

View File

@ -1,6 +0,0 @@
\documentclass{article}
\begin{document}
\cite{}
\bibliography{A.bib}
\end{document}

View File

@ -1,32 +0,0 @@
@article{art1,
title = {A fake article},
author = {Davis, J. and Jones, M.},
journal = {Journal of CI tests},
year = {2022},
description = {hintFake}
}
@book{lamport1994latex,
title = {LATEX: A Document Preparation System : User's Guide and Reference Manual},
author = {Lamport, L. and Bibby, D. and Pearson Education},
isbn = {9780201529838},
lccn = {93039691},
series = {Addison-Wesley Series on Tools},
url = {https://books.google.ch/books?id=khVUAAAAMAAJ},
year = {1994},
publisher = {Addison-Wesley},
description = {hintLaTex}
}
@book{MR1241645,
author = {Rubinstein, Reuven Y. and Shapiro, Alexander},
title = {Discrete event systems},
series = {Wiley Series in Probability and Mathematical Statistics:
Probability and Mathematical Statistics},
note = {Sensitivity analysis and stochastic optimization by the score
function method},
publisher = {John Wiley \& Sons Ltd.},
address = {Chichester},
year = 1993,
description = {hintRubi}
}

View File

@ -1,6 +0,0 @@
\documentclass{article}
\begin{document}
\cite{}
\bibliography{B.bib}
\end{document}

View File

@ -1,19 +0,0 @@
{
"folders": [
{
"path": "A"
},
{
"path": "B"
}
],
"settings": {
"latex-workshop.intellisense.citation.label":"bibtex key",
"latex-workshop.intellisense.citation.format": [
"author",
"title",
"journal",
"description"
]
}
}

View File

@ -8,29 +8,5 @@
}
],
"settings": {
"latex-workshop.latex.tools": [
{
"name": "latexmk",
"command": "latexmk",
"args": [
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
"-pdf",
"-outdir=%OUTDIR%",
"-jobname=wsA",
"%DOC%"
],
"env": {}
},
{
"name": "fake",
"command": "touch",
"args": [
"%DIR%/fake.pdf"
]
}
],
"latex-workshop.latex.recipe.default": "latexmk"
}
}

View File

@ -1,38 +0,0 @@
import * as path from 'path'
import Mocha from 'mocha'
import glob from 'glob'
export function run(): Promise<void> {
// Create the mocha test
const mocha = new Mocha({
ui: 'tdd',
color: true,
timeout: 0
})
const testsRoot = path.resolve(__dirname, '.')
return new Promise((resolve, reject) => {
glob('**/multiroot-ws.test.js', { cwd: testsRoot }, (err, files) => {
if (err) {
return reject(err)
}
// Add files to the test suite
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)))
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
reject(new Error(`${failures} tests failed.`))
} else {
resolve()
}
})
} catch (e) {
console.error(e)
reject(e)
}
})
})
}

View File

@ -1,331 +0,0 @@
import * as assert from 'assert'
import * as path from 'path'
import * as process from 'process'
import * as fs from 'fs'
import * as os from 'os'
import {sleep} from './utils/ciutils'
import {activate} from '../src/main'
import * as vscode from 'vscode'
import {
assertPdfIsGenerated,
executeVscodeCommandAfterActivation,
getFixtureDir, isDockerEnabled, runTestWithFixture,
waitGivenRootFile,
waitLatexWorkshopActivated,
promisify
} from './utils/ciutils'
function getCompletionItems(extension: vscode.Extension<ReturnType<typeof activate>>, doc: vscode.TextDocument, pos: vscode.Position): vscode.CompletionItem[] | undefined {
const token = new vscode.CancellationTokenSource().token
return extension.exports.extension.completer.provideCompletionItems?.(
doc, pos, token,
{
triggerKind: vscode.CompletionTriggerKind.Invoke,
triggerCharacter: undefined
}
)
}
function assertCompletionLabelsEqual(items: vscode.CompletionItem[] | undefined, labels: string[]) {
assert.ok(items !== undefined, 'Undefined completionItems')
assert.strictEqual(items.length, labels.length, 'Completion array has wrong length')
for(let i = 0; i<items.length; i++) {
assert.strictEqual(items[i].label, labels[i], 'Wrong label')
}
}
function assertCompletionFilterTextContains(items: vscode.CompletionItem[] | undefined, filterTexts: string[]) {
assert.ok(items !== undefined, 'Undefined completionItems')
assert.strictEqual(items.length, filterTexts.length, 'Completion array has wrong length')
for(let i = 0; i<items.length; i++) {
assert.ok(items[i].filterText && items[i].filterText?.includes(filterTexts[i]), `Wrong filterText: \n${items[i].filterText}\n${filterTexts[i]}`)
}
}
suite('Multi-root workspace test suite', () => {
suiteSetup(() => {
const config = vscode.workspace.getConfiguration()
if (process.env['LATEXWORKSHOP_CI_ENABLE_DOCKER']) {
return config.update('latex-workshop.docker.enabled', true, vscode.ConfigurationTarget.Global)
}
return
})
//
// Basic build tests
//
runTestWithFixture('fixture001', 'basic build with default recipe name', async () => {
const fixtureDir = getFixtureDir()
const wsSubDir = 'A'
const texFileName = 'A.tex'
const pdfFileName = 'wsA.pdf'
const pdfFilePath = path.join(fixtureDir, wsSubDir, pdfFileName)
await assertPdfIsGenerated(pdfFilePath, async () => {
const texFilePath = vscode.Uri.file(path.join(fixtureDir, wsSubDir, texFileName))
const doc = await vscode.workspace.openTextDocument(texFilePath)
await vscode.window.showTextDocument(doc)
await executeVscodeCommandAfterActivation('latex-workshop.build')
})
})
runTestWithFixture('fixture002', 'basic build with outDir', async () => {
const fixtureDir = getFixtureDir()
const outDir = 'out'
const wsSubDir = 'A'
const texFileName = 'A.tex'
const pdfFileName = 'A.pdf'
const pdfFilePath = path.join(fixtureDir, wsSubDir, outDir, pdfFileName)
await assertPdfIsGenerated(pdfFilePath, async () => {
const texFilePath = vscode.Uri.file(path.join(fixtureDir, wsSubDir, texFileName))
const doc = await vscode.workspace.openTextDocument(texFilePath)
await vscode.window.showTextDocument(doc)
await executeVscodeCommandAfterActivation('latex-workshop.build')
})
})
runTestWithFixture('fixture003', 'basic build with forceRecipeUsage: true', async () => {
const fixtureDir = getFixtureDir()
const wsSubDir = 'A'
const texFileName = 'A.tex'
const pdfFileName = 'A.pdf'
const pdfFilePath = path.join(fixtureDir, wsSubDir, pdfFileName)
await assertPdfIsGenerated(pdfFilePath, async () => {
const texFilePath = vscode.Uri.file(path.join(fixtureDir, wsSubDir, texFileName))
const doc = await vscode.workspace.openTextDocument(texFilePath)
await vscode.window.showTextDocument(doc)
await executeVscodeCommandAfterActivation('latex-workshop.build')
})
})
runTestWithFixture('fixture004', 'detect root with search.rootFiles.include', async () => {
const fixtureDir = getFixtureDir()
const wsSubDir = 'A'
const texFileName = 's.tex'
const pdfFileName = 'main.pdf'
const pdfFilePath = path.join(fixtureDir, wsSubDir, 'main', pdfFileName)
await assertPdfIsGenerated(pdfFilePath, async () => {
const texFilePath = vscode.Uri.file(path.join(fixtureDir, wsSubDir, 'sub', texFileName))
const doc = await vscode.workspace.openTextDocument(texFilePath)
await vscode.window.showTextDocument(doc)
await executeVscodeCommandAfterActivation('latex-workshop.build')
})
}, () => isDockerEnabled())
runTestWithFixture('fixture005', 'detect root with search.rootFiles.exclude', async () => {
const fixtureDir = getFixtureDir()
const wsSubDir = 'A'
const texFileName = 's.tex'
const pdfFileName = 'main.pdf'
const pdfFilePath = path.join(fixtureDir, wsSubDir, 'main', pdfFileName)
await assertPdfIsGenerated(pdfFilePath, async () => {
const texFilePath = vscode.Uri.file(path.join(fixtureDir, wsSubDir, 'sub', texFileName))
const doc = await vscode.workspace.openTextDocument(texFilePath)
await vscode.window.showTextDocument(doc)
await executeVscodeCommandAfterActivation('latex-workshop.build')
})
}, () => isDockerEnabled())
//
// Auto build tests
//
runTestWithFixture('fixture010', 'auto build with subfiles and onSave', async () => {
const fixtureDir = getFixtureDir()
const wsSubDir = 'A'
const texFileName = 's.tex'
const pdfFileName = 's.pdf'
const pdfFilePath = path.join(fixtureDir, wsSubDir, 'sub', pdfFileName)
await assertPdfIsGenerated(pdfFilePath, async () => {
const texFilePath = vscode.Uri.file(path.join(fixtureDir, wsSubDir, 'sub', texFileName))
const doc = await vscode.workspace.openTextDocument(texFilePath)
const editor = await vscode.window.showTextDocument(doc)
await waitLatexWorkshopActivated()
await promisify('findrootfileend')
await editor.edit((builder) => {
builder.insert(new vscode.Position(2, 0), ' ')
})
await doc.save()
})
}, () => isDockerEnabled())
runTestWithFixture('fixture011', 'auto build main.tex when editing s.tex with onSave', async () => {
const fixtureDir = getFixtureDir()
const wsSubDir = 'A'
const texFileName = 's.tex'
const pdfFileName = 'A.pdf'
const pdfFilePath = path.join(fixtureDir, wsSubDir, pdfFileName)
await assertPdfIsGenerated(pdfFilePath, async () => {
const texFilePath = vscode.Uri.file(path.join(fixtureDir, wsSubDir, 'sub', texFileName))
const doc = await vscode.workspace.openTextDocument(texFilePath)
const editor = await vscode.window.showTextDocument(doc)
await waitLatexWorkshopActivated()
await promisify('findrootfileend')
await editor.edit((builder) => {
builder.insert(new vscode.Position(2, 0), ' ')
})
await doc.save()
})
})
runTestWithFixture('fixture012', 'automatically detect root', async () => {
const fixtureDir = getFixtureDir()
const wsSubDir = 'A'
const texFileName = 's.tex'
const pdfFileName = 'A.pdf'
const pdfFilePath = path.join(fixtureDir, wsSubDir, pdfFileName)
await assertPdfIsGenerated(pdfFilePath, async () => {
const texFilePath = vscode.Uri.file(path.join(fixtureDir, wsSubDir, 'sub', texFileName))
const doc = await vscode.workspace.openTextDocument(texFilePath)
await vscode.window.showTextDocument(doc)
await executeVscodeCommandAfterActivation('latex-workshop.build')
})
})
//
// Test structure and file watcher
//
runTestWithFixture('fixture020', 'structure and file watcher', async () => {
const fixtureDir = getFixtureDir()
const texFileNameA = 'A.tex'
const texFileNameB = 'B.tex'
const texFilePathA = vscode.Uri.file(path.join(fixtureDir, 'A', texFileNameA))
const texFilePathB = vscode.Uri.file(path.join(fixtureDir, 'B', texFileNameB))
const docA = await vscode.workspace.openTextDocument(texFilePathA)
await vscode.window.showTextDocument(docA)
const extension = await waitLatexWorkshopActivated()
await waitGivenRootFile(docA.fileName)
await sleep(1000)
const docB = await vscode.workspace.openTextDocument(texFilePathB)
await vscode.window.showTextDocument(docB)
await waitGivenRootFile(docB.fileName)
await sleep(1000)
await vscode.window.showTextDocument(docA)
await waitGivenRootFile(docA.fileName)
await sleep(1000)
const structure = extension.exports.extension.structureViewer.getTreeData()
const filesWatched = extension.exports.extension.manager.getFilesWatched()
const isStructureOK = structure && structure.length > 0 && structure[0].fileName === docA.fileName
const isWatcherOK = filesWatched && filesWatched.length === 1 && filesWatched[0] === docA.fileName
assert.ok(isStructureOK, JSON.stringify(structure))
assert.ok(isWatcherOK, JSON.stringify(filesWatched))
}, () => os.platform() === 'win32')
//
// Recipe name
//
runTestWithFixture('fixture030', 'basic build with recipes and default recipe name defined in subdir', async () => {
const fixtureDir = getFixtureDir()
const wsSubDir = 'A'
const texFileName = 'A.tex'
const pdfFileName = 'wsA.pdf'
const pdfFilePath = path.join(fixtureDir, wsSubDir, pdfFileName)
await assertPdfIsGenerated(pdfFilePath, async () => {
const texFilePath = vscode.Uri.file(path.join(fixtureDir, wsSubDir, texFileName))
const doc = await vscode.workspace.openTextDocument(texFilePath)
await vscode.window.showTextDocument(doc)
await executeVscodeCommandAfterActivation('latex-workshop.build')
})
})
runTestWithFixture('fixture031', 'basic build with recipes defined in subdir and lastUsed', async () => {
const fixtureDir = getFixtureDir()
const wsSubDir = 'A'
const texFileName = 'A.tex'
const pdfFileName = 'wsA.pdf'
const pdfFilePath = path.join(fixtureDir, wsSubDir, pdfFileName)
const texFilePath = vscode.Uri.file(path.join(fixtureDir, wsSubDir, texFileName))
const doc = await vscode.workspace.openTextDocument(texFilePath)
await vscode.window.showTextDocument(doc)
await waitLatexWorkshopActivated()
await sleep(1000)
await assertPdfIsGenerated(pdfFilePath, async () => {
await vscode.commands.executeCommand('latex-workshop.recipes', 'latexmk A')
})
fs.unlinkSync(pdfFilePath)
await assertPdfIsGenerated(pdfFilePath, async () => {
await executeVscodeCommandAfterActivation('latex-workshop.build')
})
})
runTestWithFixture('fixture032', 'basic build with lastUsed and switching rootFile', async () => {
const fixtureDir = getFixtureDir()
const texFileNameA = 'A.tex'
const texFileNameB = 'B.tex'
const texFilePathA = vscode.Uri.file(path.join(fixtureDir, 'A', texFileNameA))
const texFilePathB = vscode.Uri.file(path.join(fixtureDir, 'B', texFileNameB))
const pdfFileName = 'wsA.pdf'
const pdfFilePath = path.join(fixtureDir, 'A', pdfFileName)
const docA = await vscode.workspace.openTextDocument(texFilePathA)
// Open A.tex and build
await vscode.window.showTextDocument(docA)
await waitLatexWorkshopActivated()
await waitGivenRootFile(docA.fileName)
await sleep(1000)
await assertPdfIsGenerated(pdfFilePath, async () => {
await vscode.commands.executeCommand('latex-workshop.recipes', 'latexmk A')
})
fs.unlinkSync(pdfFilePath)
// Switch to B.tex
const docB = await vscode.workspace.openTextDocument(texFilePathB)
await vscode.window.showTextDocument(docB)
await waitGivenRootFile(docB.fileName)
await sleep(1000)
// Switch back to A.tex and build
await vscode.window.showTextDocument(docA)
await waitGivenRootFile(docA.fileName)
await sleep(1000)
await assertPdfIsGenerated(pdfFilePath, async () => {
await executeVscodeCommandAfterActivation('latex-workshop.build')
})
})
runTestWithFixture('fixture040', 'citation intellisense', async () => {
const fixtureDir = getFixtureDir()
const texFileNameA = 'A.tex'
const texFileNameB = 'B.tex'
const texFilePathA = vscode.Uri.file(path.join(fixtureDir, 'A', texFileNameA))
const texFilePathB = vscode.Uri.file(path.join(fixtureDir, 'B', texFileNameB))
const docA = await vscode.workspace.openTextDocument(texFilePathA)
const pos = new vscode.Position(3,10)
const descriptions = [
'hintFake',
'hintLaTex',
'hintRubi'
]
// Open A.tex and trigger citation completion
await vscode.window.showTextDocument(docA)
const extension = await waitLatexWorkshopActivated()
await waitGivenRootFile(docA.fileName)
await sleep(1000)
const itemsA = getCompletionItems(extension, docA, pos)
const expectedLabelsA = [
'A fake article',
'LATEX: A Document Preparation System : User\'s Guide and Reference Manual',
'Discrete event systems'
]
assertCompletionLabelsEqual(itemsA, expectedLabelsA)
assertCompletionFilterTextContains(itemsA, descriptions)
// Switch to B.tex and trigger citation completion
const docB = await vscode.workspace.openTextDocument(texFilePathB)
await vscode.window.showTextDocument(docB)
await waitGivenRootFile(docB.fileName)
await sleep(10000)
const itemsB = getCompletionItems(extension, docB, pos)
const expectedLabelsB = [
'art1',
'lamport1994latex',
'MR1241645'
]
assertCompletionLabelsEqual(itemsB, expectedLabelsB)
assertCompletionFilterTextContains(itemsB, descriptions)
}, () => os.platform() === 'win32')
})

View File

@ -6,7 +6,7 @@ import { runTests } from '@vscode/test-electron'
import { getExtensionDevelopmentPath } from './utils/runnerutils'
async function runTestsOnEachFixture(targetName: 'viewer' | 'multiroot-ws') {
async function runTestsOnEachFixture(targetName: 'viewer') {
const extensionDevelopmentPath = getExtensionDevelopmentPath()
const extensionTestsPath = path.resolve(__dirname, `./${targetName}.index`)
const tmpdir = tmpFile.dirSync({ unsafeCleanup: true })
@ -52,22 +52,21 @@ async function runTestsOnEachFixture(targetName: 'viewer' | 'multiroot-ws') {
clearTimeout(nodejsTimeout)
}
}
async function runTestSuites() {
try {
const extensionDevelopmentPath = path.resolve(__dirname, '../../')
const extensionTestsPath = path.resolve(__dirname, './suites/index')
const fixtures = [
path.resolve(extensionDevelopmentPath, 'test', 'fixtures', 'testground'),
path.resolve(extensionDevelopmentPath, 'test', 'fixtures', 'multiroot')
]
const fixtures = ['testground', 'multiroot']
for (const fixture of fixtures) {
await runTests({
version: '1.71.0',
extensionDevelopmentPath,
extensionTestsPath,
launchArgs: [
fixture + path.basename(fixture) === 'multiroot' ? '/resource.code-workspace' : '',
'test/fixtures/' + fixture + (fixture === 'multiroot' ? '/resource.code-workspace' : ''),
'--user-data-dir=' + tmpFile.dirSync({ unsafeCleanup: true }).name,
'--extensions-dir=' + tmpFile.dirSync({ unsafeCleanup: true }).name
],
@ -87,7 +86,6 @@ async function main() {
try {
await runTestSuites()
await runTestsOnEachFixture('viewer')
await runTestsOnEachFixture('multiroot-ws')
} catch (err) {
console.error('Failed to run tests')
process.exit(1)

View File

@ -1,11 +1,10 @@
import * as vscode from 'vscode'
import * as path from 'path'
import * as fs from 'fs'
import rimraf from 'rimraf'
import * as assert from 'assert'
import { Extension, activate } from '../../src/main'
import { assertBuild, runTest, waitBuild, writeTeX } from './utils'
import { assertBuild, runTest, touch, waitBuild, writeTeX } from './utils'
import { sleep } from '../utils/ciutils'
suite('Build TeX files test suite', () => {
@ -45,7 +44,7 @@ suite('Build TeX files test suite', () => {
await sleep(250)
rimraf(fixture + '/*', (e) => {if (e) {console.error(e)}})
await sleep(250)
fs.closeSync(fs.openSync(path.resolve(fixture, '.gitkeep'), 'a'))
touch(path.resolve(fixture, '.gitkeep'))
}
})

View File

@ -1,11 +1,10 @@
import * as vscode from 'vscode'
import * as path from 'path'
import * as fs from 'fs'
import * as assert from 'assert'
import rimraf from 'rimraf'
import { Extension, activate } from '../../src/main'
import { assertAutoBuild, assertBuild, runTest, writeTeX } from './utils'
import { assertAutoBuild, assertBuild, runTest, touch, writeTeX } from './utils'
import { sleep } from '../utils/ciutils'
suite('Auto-build test suite', () => {
@ -46,7 +45,7 @@ suite('Auto-build test suite', () => {
await sleep(250)
rimraf(fixture + '/*', (e) => {if (e) {console.error(e)}})
await sleep(250)
fs.closeSync(fs.openSync(fixture + '/.gitkeep', 'a'))
touch(fixture + '/.gitkeep')
}
})

View File

@ -1,11 +1,10 @@
import * as vscode from 'vscode'
import * as path from 'path'
import * as fs from 'fs'
import rimraf from 'rimraf'
import * as assert from 'assert'
import { Extension, activate } from '../../src/main'
import { runTest, writeTeX } from './utils'
import { runTest, touch, writeTeX } from './utils'
import { sleep } from '../utils/ciutils'
suite('Find root file test suite', () => {
@ -36,7 +35,7 @@ suite('Find root file test suite', () => {
await sleep(250)
rimraf(fixture + '/*', (e) => {if (e) {console.error(e)}})
await sleep(250)
fs.closeSync(fs.openSync(path.resolve(fixture, '.gitkeep'), 'a'))
touch(path.resolve(fixture, '.gitkeep'))
}
})

View File

@ -1,11 +1,10 @@
import * as vscode from 'vscode'
import * as path from 'path'
import * as fs from 'fs'
import rimraf from 'rimraf'
import * as assert from 'assert'
import { Extension, activate } from '../../src/main'
import { runTest, writeTeX } from './utils'
import { runTest, touch, writeTeX } from './utils'
import { sleep } from '../utils/ciutils'
suite('Intellisense test suite', () => {
@ -39,7 +38,7 @@ suite('Intellisense test suite', () => {
await sleep(250)
rimraf(fixture + '/*', (e) => {if (e) {console.error(e)}})
await sleep(250)
fs.closeSync(fs.openSync(path.resolve(fixture, '.gitkeep'), 'a'))
touch(path.resolve(fixture, '.gitkeep'))
}
})

View File

@ -1,11 +1,10 @@
import * as vscode from 'vscode'
import * as path from 'path'
import * as fs from 'fs'
import rimraf from 'rimraf'
import * as assert from 'assert'
import { Extension, activate } from '../../src/main'
import { runTest, writeTeX, assertBuild } from './utils'
import { runTest, writeTeX, assertBuild, touch, assertAutoBuild } from './utils'
import { sleep } from '../utils/ciutils'
suite('Multi-root workspace test suite', () => {
@ -32,26 +31,144 @@ suite('Multi-root workspace test suite', () => {
extension.manager.rootFile = undefined
}
await vscode.workspace.getConfiguration().update('latex-workshop.latex.tools', undefined)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.outDir', undefined)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.recipes', undefined)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.build.forceRecipeUsage', undefined)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.search.rootFiles.include', undefined)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.search.rootFiles.exclude', undefined)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.autoBuild.run', undefined)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.doNotPrompt', undefined)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.useSubFile', undefined)
if (path.basename(fixture) === 'multiroot') {
await sleep(250)
rimraf(fixture + '/A/*', (e) => {if (e) {console.error(e)}})
rimraf(fixture + '/B/*', (e) => {if (e) {console.error(e)}})
await sleep(250)
fs.closeSync(fs.openSync(path.resolve(fixture, 'A', '.gitkeep'), 'a'))
fs.closeSync(fs.openSync(path.resolve(fixture, 'B', '.gitkeep'), 'a'))
touch(path.resolve(fixture, 'A', '.gitkeep'))
touch(path.resolve(fixture, 'B', '.gitkeep'))
}
})
runTest({suiteName, fixtureName, testName: 'basic completion'}, async () => {
runTest({suiteName, fixtureName, testName: 'basic build A'}, async () => {
const tools = [
{name: 'latexmk', command: 'latexmk', args: ['-synctex=1', '-interaction=nonstopmode', '-file-line-error', '-pdf', '-outdir=%OUTDIR%', '-jobname=wsA', '%DOC%'], env: {}},
{name: 'fake', command: 'touch', args: ['%DIR%/fake.pdf']}
]
const recipes = [{name: 'latexmk', tools: ['latexmk']}]
await vscode.workspace.getConfiguration().update('latex-workshop.latex.tools', tools)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.recipe.default', 'latexmk')
await vscode.workspace.getConfiguration().update('latex-workshop.latex.recipes', recipes)
await writeTeX('main', fixture, {fileName: 'A/main.tex'})
fs.closeSync(fs.openSync(path.resolve(fixture, 'B', 'empty'), 'a'))
touch(path.resolve(fixture, 'B', 'empty'))
await assertBuild({fixture, texFileName: 'A/main.tex', pdfFileName: 'A/wsA.pdf', extension})
})
runTest({suiteName, fixtureName, testName: 'basic build B'}, async () => {
const tools = [
{name: 'latexmk', command: 'latexmk', args: ['-synctex=1', '-interaction=nonstopmode', '-file-line-error', '-pdf', '-outdir=%OUTDIR%', '-jobname=wsB', '%DOC%'], env: {}},
{name: 'fake', command: 'touch', args: ['%DIR%/fake.pdf']}
]
const recipes = [{name: 'latexmk', tools: ['latexmk']}]
await vscode.workspace.getConfiguration().update('latex-workshop.latex.tools', tools)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.recipes', recipes)
await writeTeX('main', fixture, {fileName: 'B/main.tex'})
touch(path.resolve(fixture, 'A', 'empty'))
await assertBuild({fixture, texFileName: 'B/main.tex', pdfFileName: 'B/wsB.pdf', extension})
})
runTest({suiteName, fixtureName, testName: 'basic build with outDir A'}, async () => {
await vscode.workspace.getConfiguration().update('latex-workshop.latex.outDir', './out')
await writeTeX('main', fixture, {fileName: 'A/main.tex'})
touch(path.resolve(fixture, 'B', 'empty'))
await assertBuild({fixture, texFileName: 'A/main.tex', pdfFileName: 'A/out/main.pdf', extension})
})
runTest({suiteName, fixtureName, testName: 'basic build with outDir B'}, async () => {
await vscode.workspace.getConfiguration().update('latex-workshop.latex.outDir', './out')
await writeTeX('main', fixture, {fileName: 'B/main.tex'})
touch(path.resolve(fixture, 'A', 'empty'))
await assertBuild({fixture, texFileName: 'B/main.tex', pdfFileName: 'B/out/main.pdf', extension})
})
runTest({suiteName, fixtureName, testName: 'build with forceRecipeUsage: true'}, async () => {
await vscode.workspace.getConfiguration().update('latex-workshop.latex.build.forceRecipeUsage', true)
await writeTeX('magicinvalidprogram', fixture, {fileName: 'A/main.tex'})
touch(path.resolve(fixture, 'B', 'empty'))
await assertBuild({fixture, texFileName: 'A/main.tex', pdfFileName: 'A/main.pdf', extension})
})
runTest({suiteName, fixtureName, testName: 'detect root with search.rootFiles.include'}, async () => {
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.doNotPrompt', true)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.search.rootFiles.include', ['alt/*.tex'])
await writeTeX('subfiletwomain', fixture, {fileDir: 'A/'})
touch(path.resolve(fixture, 'B', 'empty'))
await assertBuild({fixture, texFileName: 'A/sub/s.tex', pdfFileName: 'A/alt/main.pdf', extension})
})
runTest({suiteName, fixtureName, testName: 'detect root with search.rootFiles.exclude'}, async () => {
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.doNotPrompt', true)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.search.rootFiles.exclude', ['*.tex'])
await writeTeX('subfiletwomain', fixture, {fileDir: 'A/'})
touch(path.resolve(fixture, 'B', 'empty'))
await assertBuild({fixture, texFileName: 'A/sub/s.tex', pdfFileName: 'A/alt/main.pdf', extension})
})
runTest({suiteName, fixtureName, testName: 'auto-detect subfile root A1'}, async () => {
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.doNotPrompt', true)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.useSubFile', true)
await writeTeX('subfile', fixture, {fileDir: 'A/'})
touch(path.resolve(fixture, 'B', 'empty'))
await assertBuild({fixture, texFileName: 'A/sub/s.tex', pdfFileName: 'A/sub/s.pdf', extension})
})
runTest({suiteName, fixtureName, testName: 'auto-detect subfile root A2'}, async () => {
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.doNotPrompt', true)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.useSubFile', false)
await writeTeX('subfile', fixture, {fileDir: 'A/'})
touch(path.resolve(fixture, 'B', 'empty'))
await assertBuild({fixture, texFileName: 'A/sub/s.tex', pdfFileName: 'A/main.pdf', extension})
})
runTest({suiteName, fixtureName, testName: 'auto-detect subfile root B1'}, async () => {
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.doNotPrompt', true)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.useSubFile', true)
await writeTeX('subfile', fixture, {fileDir: 'B/'})
touch(path.resolve(fixture, 'A', 'empty'))
await assertBuild({fixture, texFileName: 'B/sub/s.tex', pdfFileName: 'B/sub/s.pdf', extension})
})
runTest({suiteName, fixtureName, testName: 'auto-detect subfile root B2'}, async () => {
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.doNotPrompt', true)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.useSubFile', false)
await writeTeX('subfile', fixture, {fileDir: 'B/'})
touch(path.resolve(fixture, 'A', 'empty'))
await assertBuild({fixture, texFileName: 'B/sub/s.tex', pdfFileName: 'B/main.pdf', extension})
})
runTest({suiteName, fixtureName, testName: 'auto build with subfiles and onSave 1'}, async () => {
await vscode.workspace.getConfiguration().update('latex-workshop.latex.autoBuild.run', 'onSave')
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.doNotPrompt', true)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.useSubFile', false)
await writeTeX('subfile', fixture, {fileDir: 'A/'})
touch(path.resolve(fixture, 'B', 'empty'))
await assertAutoBuild({fixture, texFileName: 'A/sub/s.tex', pdfFileName: 'A/main.pdf', extension}, 'onSave')
})
runTest({suiteName, fixtureName, testName: 'auto build with subfiles and onSave 2'}, async () => {
await vscode.workspace.getConfiguration().update('latex-workshop.latex.autoBuild.run', 'onSave')
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.doNotPrompt', true)
await vscode.workspace.getConfiguration().update('latex-workshop.latex.rootFile.useSubFile', true)
await writeTeX('subfile', fixture, {fileDir: 'A/'})
touch(path.resolve(fixture, 'B', 'empty'))
await assertAutoBuild({fixture, texFileName: 'A/sub/s.tex', pdfFileName: 'A/sub/s.pdf', extension}, 'onSave')
})
runTest({suiteName, fixtureName, testName: 'switching rootFile'}, async () => {
await writeTeX('main', fixture, {fileName: 'A/main.tex'})
await writeTeX('main', fixture, {fileName: 'B/main.tex'})
await assertBuild({fixture, texFileName: 'A/main.tex', pdfFileName: 'A/main.pdf', extension, removepdf: true})
await assertBuild({fixture, texFileName: 'B/main.tex', pdfFileName: 'B/main.pdf', extension, removepdf: true})
await assertBuild({fixture, texFileName: 'A/main.tex', pdfFileName: 'A/main.pdf', extension})
})
})

View File

@ -6,6 +6,10 @@ import * as os from 'os'
import * as assert from 'assert'
import { Extension } from '../../src/main'
export function touch(filePath: string) {
fs.closeSync(fs.openSync(filePath, 'a'))
}
type RunTestOption = {
suiteName: string,
fixtureName: string,
@ -81,7 +85,8 @@ type AssertBuildOption = {
pdfFileName: string,
extension?: Extension,
build?: () => unknown,
nobuild?: boolean
nobuild?: boolean,
removepdf?: boolean
}
export async function assertBuild(option: AssertBuildOption) {
@ -98,6 +103,14 @@ export async function assertBuild(option: AssertBuildOption) {
const files = glob.sync('**/**.pdf', { cwd: option.fixture })
assert.strictEqual(files.map(file => path.resolve(option.fixture, file)).join(','), option.pdfFileName === '' ? option.pdfFileName : pdfFilePath)
if (option.removepdf) {
files.forEach(async file => {
if (fs.existsSync(path.join(option.fixture, file))) {
fs.unlinkSync(path.join(option.fixture, file))
await sleep(250)
}
})
}
}
export async function assertAutoBuild(option: AssertBuildOption, mode?: 'skipFirstBuild' | 'noAutoBuild' | 'onSave') {
@ -114,6 +127,9 @@ export async function assertAutoBuild(option: AssertBuildOption, mode?: 'skipFir
if (mode !== 'onSave') {
fs.appendFileSync(path.resolve(option.fixture, option.texFileName), ' % edit')
} else {
await sleep(250)
await vscode.commands.executeCommand('workbench.action.files.save')
await sleep(250)
await vscode.commands.executeCommand('workbench.action.files.save')
}
@ -141,7 +157,7 @@ type WriteTeXType = 'main' | 'makeindex' | 'makesubfileindex' | 'magicprogram' |
'subfile' | 'subfileverbatim' | 'subfiletwomain' | 'subfilethreelayer' | 'importthreelayer' | 'bibtex' |
'input' | 'inputmacro' | 'inputfromfolder' | 'circularinclude' | 'intellisense' | 'structure' | 'linter'
export async function writeTeX(type: WriteTeXType, fixture: string, payload?: {fileName?: string}) {
export async function writeTeX(type: WriteTeXType, fixture: string, payload?: {fileName?: string, fileDir?: string}) {
switch (type) {
case 'main':
writeTest({fixture, fileName: payload?.fileName || 'main.tex'}, '\\documentclass{article}', '\\begin{document}', 'abc', '\\end{document}')
@ -165,7 +181,7 @@ export async function writeTeX(type: WriteTeXType, fixture: string, payload?: {f
writeTest({fixture, fileName: 'sub/s.tex'}, '% !TEX root = ../main.tex', 'sub sub')
break
case 'magicinvalidprogram':
writeTest({fixture, fileName: 'main.tex'}, '% !TEX program = noexistprogram', '\\documentclass{article}', '\\begin{document}', 'abc', '\\end{document}')
writeTest({fixture, fileName: payload?.fileName || 'main.tex'}, '% !TEX program = noexistprogram', '\\documentclass{article}', '\\begin{document}', 'abc', '\\end{document}')
break
case 'input':
writeTest({fixture, fileName: 'main.tex'}, '\\documentclass{article}', '\\begin{document}', 'main main', '\\input{sub/s}', '\\end{document}')
@ -184,17 +200,17 @@ export async function writeTeX(type: WriteTeXType, fixture: string, payload?: {f
writeTest({fixture, fileName: 'bib.bib'}, '%')
break
case 'subfile':
writeTest({fixture, fileName: 'main.tex'}, '\\documentclass{article}', '\\usepackage{subfiles}', '\\begin{document}', 'main main', '\\subfile{sub/s}', '\\end{document}')
writeTest({fixture, fileName: 'sub/s.tex'}, '\\documentclass[../main.tex]{subfiles}', '\\begin{document}', 'sub sub', '\\end{document}')
writeTest({fixture, fileName: (payload?.fileDir || '') + 'main.tex'}, '\\documentclass{article}', '\\usepackage{subfiles}', '\\begin{document}', 'main main', '\\subfile{sub/s}', '\\end{document}')
writeTest({fixture, fileName: (payload?.fileDir || '') + 'sub/s.tex'}, '\\documentclass[../main.tex]{subfiles}', '\\begin{document}', 'sub sub', '\\end{document}')
break
case 'subfileverbatim':
writeTest({fixture, fileName: 'main.tex'}, '\\documentclass{article}', '\\begin{document}', 'main main', '\\input{sub/s}', '\\end{document}')
writeTest({fixture, fileName: 'sub/s.tex'}, '\\section{Introduction}', 'This is a minimum \\LaTeX\\ document:', '\\begin{verbatim}', '\\documentclass{article}', '\\begin{document}', 'sub sub', '\\end{document}', '\\end{verbatim}')
break
case 'subfiletwomain':
writeTest({fixture, fileName: 'main.tex'}, '\\documentclass{article}', '\\usepackage{subfiles}', '\\begin{document}', 'main main', '\\subfile{sub/s}', '\\end{document}')
writeTest({fixture, fileName: 'alt/main.tex'}, '\\documentclass{article}', '\\begin{document}', 'alt alt', '\\input{../sub/s}', '\\end{document}')
writeTest({fixture, fileName: 'sub/s.tex'}, 'sub sub')
writeTest({fixture, fileName: (payload?.fileDir || '') + 'main.tex'}, '\\documentclass{article}', '\\usepackage{subfiles}', '\\begin{document}', 'main main', '\\subfile{sub/s}', '\\end{document}')
writeTest({fixture, fileName: (payload?.fileDir || '') + 'alt/main.tex'}, '\\documentclass{article}', '\\begin{document}', 'alt alt', '\\input{../sub/s}', '\\end{document}')
writeTest({fixture, fileName: (payload?.fileDir || '') + 'sub/s.tex'}, 'sub sub')
break
case 'subfilethreelayer':
writeTest({fixture, fileName: 'main.tex'}, '\\documentclass{article}', '\\usepackage{subfiles}', '\\begin{document}', 'main main', '\\subfile{sub/s}', '\\end{document}')