brighterscript 0.72.1 → 0.72.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -2
- package/dist/LanguageServer.d.ts +2 -1
- package/dist/LanguageServer.js +12 -0
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Program.d.ts +5 -1
- package/dist/Program.js +20 -0
- package/dist/Program.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +2 -1
- package/dist/bscPlugin/BscPlugin.js +4 -0
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/inlayHints/InlayHintProcessor.d.ts +23 -0
- package/dist/bscPlugin/inlayHints/InlayHintProcessor.js +183 -0
- package/dist/bscPlugin/inlayHints/InlayHintProcessor.js.map +1 -0
- package/dist/interfaces.d.ts +34 -1
- package/dist/lsp/LspProject.d.ts +8 -1
- package/dist/lsp/Project.d.ts +5 -1
- package/dist/lsp/Project.js +6 -0
- package/dist/lsp/Project.js.map +1 -1
- package/dist/lsp/ProjectManager.d.ts +5 -1
- package/dist/lsp/ProjectManager.js +12 -0
- package/dist/lsp/ProjectManager.js.map +1 -1
- package/dist/lsp/worker/WorkerThreadProject.d.ts +5 -1
- package/dist/lsp/worker/WorkerThreadProject.js +3 -0
- package/dist/lsp/worker/WorkerThreadProject.js.map +1 -1
- package/package.json +18 -14
- package/dist/astUtils/AstEditor.spec.d.ts +0 -1
- package/dist/astUtils/AstEditor.spec.js +0 -254
- package/dist/astUtils/AstEditor.spec.js.map +0 -1
- package/dist/astUtils/creators.spec.d.ts +0 -1
- package/dist/astUtils/creators.spec.js +0 -21
- package/dist/astUtils/creators.spec.js.map +0 -1
- package/dist/astUtils/reflection.spec.d.ts +0 -1
- package/dist/astUtils/reflection.spec.js +0 -308
- package/dist/astUtils/reflection.spec.js.map +0 -1
- package/dist/astUtils/stackedVisitor.spec.d.ts +0 -1
- package/dist/astUtils/stackedVisitor.spec.js +0 -79
- package/dist/astUtils/stackedVisitor.spec.js.map +0 -1
- package/dist/astUtils/visitors.spec.d.ts +0 -1
- package/dist/astUtils/visitors.spec.js +0 -1197
- package/dist/astUtils/visitors.spec.js.map +0 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +0 -1237
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/definition/DefinitionProvider.spec.d.ts +0 -1
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js +0 -171
- package/dist/bscPlugin/definition/DefinitionProvider.spec.js.map +0 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +0 -201
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/references/ReferencesProvider.spec.d.ts +0 -1
- package/dist/bscPlugin/references/ReferencesProvider.spec.js +0 -51
- package/dist/bscPlugin/references/ReferencesProvider.spec.js.map +0 -1
- package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.spec.js +0 -298
- package/dist/bscPlugin/selectionRanges/SelectionRangesProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +0 -399
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js +0 -290
- package/dist/bscPlugin/symbols/DocumentSymbolProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js +0 -245
- package/dist/bscPlugin/symbols/WorkspaceSymbolProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.d.ts +0 -1
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js +0 -46
- package/dist/bscPlugin/transpile/BrsFilePreTranspileProcessor.spec.js.map +0 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.d.ts +0 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +0 -702
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +0 -1
- package/dist/common/Sequencer.spec.d.ts +0 -1
- package/dist/common/Sequencer.spec.js +0 -75
- package/dist/common/Sequencer.spec.js.map +0 -1
- package/dist/files/BrsFile.Class.spec.d.ts +0 -1
- package/dist/files/BrsFile.Class.spec.js +0 -1805
- package/dist/files/BrsFile.Class.spec.js.map +0 -1
- package/dist/files/BrsFile.spec.d.ts +0 -1
- package/dist/files/BrsFile.spec.js +0 -4611
- package/dist/files/BrsFile.spec.js.map +0 -1
- package/dist/files/XmlFile.spec.d.ts +0 -1
- package/dist/files/XmlFile.spec.js +0 -1219
- package/dist/files/XmlFile.spec.js.map +0 -1
- package/dist/files/tests/imports.spec.d.ts +0 -1
- package/dist/files/tests/imports.spec.js +0 -241
- package/dist/files/tests/imports.spec.js.map +0 -1
- package/dist/files/tests/optionalChaning.spec.d.ts +0 -1
- package/dist/files/tests/optionalChaning.spec.js +0 -152
- package/dist/files/tests/optionalChaning.spec.js.map +0 -1
- package/dist/lexer/Character.spec.d.ts +0 -1
- package/dist/lexer/Character.spec.js +0 -27
- package/dist/lexer/Character.spec.js.map +0 -1
- package/dist/lexer/Lexer.spec.d.ts +0 -1
- package/dist/lexer/Lexer.spec.js +0 -1300
- package/dist/lexer/Lexer.spec.js.map +0 -1
- package/dist/lsp/ActionQueue.spec.d.ts +0 -1
- package/dist/lsp/ActionQueue.spec.js +0 -80
- package/dist/lsp/ActionQueue.spec.js.map +0 -1
- package/dist/lsp/DocumentManager.spec.d.ts +0 -1
- package/dist/lsp/DocumentManager.spec.js +0 -103
- package/dist/lsp/DocumentManager.spec.js.map +0 -1
- package/dist/lsp/PathFilterer.spec.d.ts +0 -1
- package/dist/lsp/PathFilterer.spec.js +0 -182
- package/dist/lsp/PathFilterer.spec.js.map +0 -1
- package/dist/lsp/Project.spec.d.ts +0 -1
- package/dist/lsp/Project.spec.js +0 -400
- package/dist/lsp/Project.spec.js.map +0 -1
- package/dist/lsp/ProjectManager.spec.d.ts +0 -1
- package/dist/lsp/ProjectManager.spec.js +0 -1183
- package/dist/lsp/ProjectManager.spec.js.map +0 -1
- package/dist/lsp/worker/MessageHandler.spec.d.ts +0 -1
- package/dist/lsp/worker/MessageHandler.spec.js +0 -64
- package/dist/lsp/worker/MessageHandler.spec.js.map +0 -1
- package/dist/lsp/worker/WorkerPool.spec.d.ts +0 -1
- package/dist/lsp/worker/WorkerPool.spec.js +0 -59
- package/dist/lsp/worker/WorkerPool.spec.js.map +0 -1
- package/dist/lsp/worker/WorkerThreadProject.spec.d.ts +0 -2
- package/dist/lsp/worker/WorkerThreadProject.spec.js +0 -72
- package/dist/lsp/worker/WorkerThreadProject.spec.js.map +0 -1
- package/dist/parser/AstNode.spec.d.ts +0 -1
- package/dist/parser/AstNode.spec.js +0 -1452
- package/dist/parser/AstNode.spec.js.map +0 -1
- package/dist/parser/Expression.spec.d.ts +0 -1
- package/dist/parser/Expression.spec.js +0 -40
- package/dist/parser/Expression.spec.js.map +0 -1
- package/dist/parser/Parser.Class.spec.d.ts +0 -1
- package/dist/parser/Parser.Class.spec.js +0 -495
- package/dist/parser/Parser.Class.spec.js.map +0 -1
- package/dist/parser/Parser.spec.d.ts +0 -4
- package/dist/parser/Parser.spec.js +0 -1985
- package/dist/parser/Parser.spec.js.map +0 -1
- package/dist/parser/SGParser.spec.d.ts +0 -1
- package/dist/parser/SGParser.spec.js +0 -131
- package/dist/parser/SGParser.spec.js.map +0 -1
- package/dist/parser/Statement.spec.d.ts +0 -1
- package/dist/parser/Statement.spec.js +0 -118
- package/dist/parser/Statement.spec.js.map +0 -1
- package/dist/parser/tests/Parser.spec.d.ts +0 -19
- package/dist/parser/tests/Parser.spec.js +0 -38
- package/dist/parser/tests/Parser.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/For.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/For.spec.js +0 -208
- package/dist/parser/tests/controlFlow/For.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/ForEach.spec.js +0 -143
- package/dist/parser/tests/controlFlow/ForEach.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/If.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/If.spec.js +0 -570
- package/dist/parser/tests/controlFlow/If.spec.js.map +0 -1
- package/dist/parser/tests/controlFlow/While.spec.d.ts +0 -1
- package/dist/parser/tests/controlFlow/While.spec.js +0 -156
- package/dist/parser/tests/controlFlow/While.spec.js.map +0 -1
- package/dist/parser/tests/expression/Additive.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Additive.spec.js +0 -99
- package/dist/parser/tests/expression/Additive.spec.js.map +0 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.d.ts +0 -1
- package/dist/parser/tests/expression/ArrayLiterals.spec.js +0 -291
- package/dist/parser/tests/expression/ArrayLiterals.spec.js.map +0 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.d.ts +0 -1
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js +0 -401
- package/dist/parser/tests/expression/AssociativeArrayLiterals.spec.js.map +0 -1
- package/dist/parser/tests/expression/Boolean.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Boolean.spec.js +0 -83
- package/dist/parser/tests/expression/Boolean.spec.js.map +0 -1
- package/dist/parser/tests/expression/Call.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Call.spec.js +0 -242
- package/dist/parser/tests/expression/Call.spec.js.map +0 -1
- package/dist/parser/tests/expression/Exponential.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Exponential.spec.js +0 -37
- package/dist/parser/tests/expression/Exponential.spec.js.map +0 -1
- package/dist/parser/tests/expression/Function.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Function.spec.js +0 -403
- package/dist/parser/tests/expression/Function.spec.js.map +0 -1
- package/dist/parser/tests/expression/Indexing.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Indexing.spec.js +0 -289
- package/dist/parser/tests/expression/Indexing.spec.js.map +0 -1
- package/dist/parser/tests/expression/Multiplicative.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Multiplicative.spec.js +0 -67
- package/dist/parser/tests/expression/Multiplicative.spec.js.map +0 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +0 -346
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.d.ts +0 -1
- package/dist/parser/tests/expression/PrefixUnary.spec.js +0 -105
- package/dist/parser/tests/expression/PrefixUnary.spec.js.map +0 -1
- package/dist/parser/tests/expression/Primary.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Primary.spec.js +0 -149
- package/dist/parser/tests/expression/Primary.spec.js.map +0 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js +0 -171
- package/dist/parser/tests/expression/RegexLiteralExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/Relational.spec.d.ts +0 -1
- package/dist/parser/tests/expression/Relational.spec.js +0 -83
- package/dist/parser/tests/expression/Relational.spec.js.map +0 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js +0 -201
- package/dist/parser/tests/expression/SourceLiteralExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +0 -389
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +0 -876
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +0 -1
- package/dist/parser/tests/expression/UnaryExpression.spec.d.ts +0 -1
- package/dist/parser/tests/expression/UnaryExpression.spec.js +0 -52
- package/dist/parser/tests/expression/UnaryExpression.spec.js.map +0 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.d.ts +0 -1
- package/dist/parser/tests/statement/AssignmentOperators.spec.js +0 -79
- package/dist/parser/tests/statement/AssignmentOperators.spec.js.map +0 -1
- package/dist/parser/tests/statement/ConstStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/ConstStatement.spec.js +0 -708
- package/dist/parser/tests/statement/ConstStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/Continue.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Continue.spec.js +0 -119
- package/dist/parser/tests/statement/Continue.spec.js.map +0 -1
- package/dist/parser/tests/statement/Declaration.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Declaration.spec.js +0 -108
- package/dist/parser/tests/statement/Declaration.spec.js.map +0 -1
- package/dist/parser/tests/statement/Dim.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Dim.spec.js +0 -73
- package/dist/parser/tests/statement/Dim.spec.js.map +0 -1
- package/dist/parser/tests/statement/Enum.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Enum.spec.js +0 -1307
- package/dist/parser/tests/statement/Enum.spec.js.map +0 -1
- package/dist/parser/tests/statement/For.spec.d.ts +0 -1
- package/dist/parser/tests/statement/For.spec.js +0 -45
- package/dist/parser/tests/statement/For.spec.js.map +0 -1
- package/dist/parser/tests/statement/ForEach.spec.d.ts +0 -1
- package/dist/parser/tests/statement/ForEach.spec.js +0 -36
- package/dist/parser/tests/statement/ForEach.spec.js.map +0 -1
- package/dist/parser/tests/statement/Function.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Function.spec.js +0 -342
- package/dist/parser/tests/statement/Function.spec.js.map +0 -1
- package/dist/parser/tests/statement/Goto.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Goto.spec.js +0 -51
- package/dist/parser/tests/statement/Goto.spec.js.map +0 -1
- package/dist/parser/tests/statement/Increment.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Increment.spec.js +0 -117
- package/dist/parser/tests/statement/Increment.spec.js.map +0 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/InterfaceStatement.spec.js +0 -102
- package/dist/parser/tests/statement/InterfaceStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/LibraryStatement.spec.js +0 -74
- package/dist/parser/tests/statement/LibraryStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/Misc.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Misc.spec.js +0 -335
- package/dist/parser/tests/statement/Misc.spec.js.map +0 -1
- package/dist/parser/tests/statement/PrintStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/PrintStatement.spec.js +0 -195
- package/dist/parser/tests/statement/PrintStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.d.ts +0 -1
- package/dist/parser/tests/statement/ReturnStatement.spec.js +0 -94
- package/dist/parser/tests/statement/ReturnStatement.spec.js.map +0 -1
- package/dist/parser/tests/statement/Set.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Set.spec.js +0 -218
- package/dist/parser/tests/statement/Set.spec.js.map +0 -1
- package/dist/parser/tests/statement/Stop.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Stop.spec.js +0 -38
- package/dist/parser/tests/statement/Stop.spec.js.map +0 -1
- package/dist/parser/tests/statement/Throw.spec.d.ts +0 -1
- package/dist/parser/tests/statement/Throw.spec.js +0 -35
- package/dist/parser/tests/statement/Throw.spec.js.map +0 -1
- package/dist/parser/tests/statement/TryCatch.spec.d.ts +0 -1
- package/dist/parser/tests/statement/TryCatch.spec.js +0 -142
- package/dist/parser/tests/statement/TryCatch.spec.js.map +0 -1
- package/dist/preprocessor/Manifest.spec.d.ts +0 -1
- package/dist/preprocessor/Manifest.spec.js +0 -80
- package/dist/preprocessor/Manifest.spec.js.map +0 -1
- package/dist/preprocessor/Preprocessor.spec.d.ts +0 -1
- package/dist/preprocessor/Preprocessor.spec.js +0 -152
- package/dist/preprocessor/Preprocessor.spec.js.map +0 -1
- package/dist/preprocessor/PreprocessorParser.spec.d.ts +0 -1
- package/dist/preprocessor/PreprocessorParser.spec.js +0 -116
- package/dist/preprocessor/PreprocessorParser.spec.js.map +0 -1
- package/dist/types/ArrayType.spec.d.ts +0 -1
- package/dist/types/ArrayType.spec.js +0 -30
- package/dist/types/ArrayType.spec.js.map +0 -1
- package/dist/types/BooleanType.spec.d.ts +0 -1
- package/dist/types/BooleanType.spec.js +0 -12
- package/dist/types/BooleanType.spec.js.map +0 -1
- package/dist/types/DoubleType.spec.d.ts +0 -1
- package/dist/types/DoubleType.spec.js +0 -12
- package/dist/types/DoubleType.spec.js.map +0 -1
- package/dist/types/DynamicType.spec.d.ts +0 -1
- package/dist/types/DynamicType.spec.js +0 -12
- package/dist/types/DynamicType.spec.js.map +0 -1
- package/dist/types/FloatType.spec.d.ts +0 -1
- package/dist/types/FloatType.spec.js +0 -12
- package/dist/types/FloatType.spec.js.map +0 -1
- package/dist/types/FunctionType.spec.d.ts +0 -1
- package/dist/types/FunctionType.spec.js +0 -23
- package/dist/types/FunctionType.spec.js.map +0 -1
- package/dist/types/IntegerType.spec.d.ts +0 -1
- package/dist/types/IntegerType.spec.js +0 -12
- package/dist/types/IntegerType.spec.js.map +0 -1
- package/dist/types/InterfaceType.spec.d.ts +0 -1
- package/dist/types/InterfaceType.spec.js +0 -175
- package/dist/types/InterfaceType.spec.js.map +0 -1
- package/dist/types/InvalidType.spec.d.ts +0 -1
- package/dist/types/InvalidType.spec.js +0 -12
- package/dist/types/InvalidType.spec.js.map +0 -1
- package/dist/types/LongIntegerType.spec.d.ts +0 -1
- package/dist/types/LongIntegerType.spec.js +0 -12
- package/dist/types/LongIntegerType.spec.js.map +0 -1
- package/dist/types/ObjectType.spec.d.ts +0 -1
- package/dist/types/ObjectType.spec.js +0 -12
- package/dist/types/ObjectType.spec.js.map +0 -1
- package/dist/types/StringType.spec.d.ts +0 -1
- package/dist/types/StringType.spec.js +0 -12
- package/dist/types/StringType.spec.js.map +0 -1
- package/dist/types/VoidType.spec.d.ts +0 -1
- package/dist/types/VoidType.spec.js +0 -12
- package/dist/types/VoidType.spec.js.map +0 -1
|
@@ -1,1183 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const chai_1 = require("chai");
|
|
4
|
-
const ProjectManager_1 = require("./ProjectManager");
|
|
5
|
-
const testHelpers_spec_1 = require("../testHelpers.spec");
|
|
6
|
-
const fsExtra = require("fs-extra");
|
|
7
|
-
const util_1 = require("../util");
|
|
8
|
-
const sinon_1 = require("sinon");
|
|
9
|
-
const Project_1 = require("./Project");
|
|
10
|
-
const WorkerThreadProject_1 = require("./worker/WorkerThreadProject");
|
|
11
|
-
const WorkerThreadProject_spec_1 = require("./worker/WorkerThreadProject.spec");
|
|
12
|
-
const DiagnosticMessages_1 = require("../DiagnosticMessages");
|
|
13
|
-
const vscode_languageserver_protocol_1 = require("vscode-languageserver-protocol");
|
|
14
|
-
const PathFilterer_1 = require("./PathFilterer");
|
|
15
|
-
const deferred_1 = require("../deferred");
|
|
16
|
-
const net = require("net");
|
|
17
|
-
const getPort = require("get-port");
|
|
18
|
-
const sinon = (0, sinon_1.createSandbox)();
|
|
19
|
-
describe('ProjectManager', () => {
|
|
20
|
-
let manager;
|
|
21
|
-
let pathFilterer;
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
pathFilterer = new PathFilterer_1.PathFilterer();
|
|
24
|
-
manager = new ProjectManager_1.ProjectManager({
|
|
25
|
-
pathFilterer: pathFilterer
|
|
26
|
-
});
|
|
27
|
-
fsExtra.emptyDirSync(testHelpers_spec_1.tempDir);
|
|
28
|
-
sinon.restore();
|
|
29
|
-
diagnosticsListeners = [];
|
|
30
|
-
diagnosticsResponses = [];
|
|
31
|
-
manager.on('diagnostics', (event) => {
|
|
32
|
-
var _a;
|
|
33
|
-
if (diagnosticsListeners.length > 0) {
|
|
34
|
-
(_a = diagnosticsListeners.shift()) === null || _a === void 0 ? void 0 : _a(event.diagnostics);
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
diagnosticsResponses.push(event.diagnostics);
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
afterEach(() => {
|
|
42
|
-
fsExtra.emptyDirSync(testHelpers_spec_1.tempDir);
|
|
43
|
-
sinon.restore();
|
|
44
|
-
manager.dispose();
|
|
45
|
-
});
|
|
46
|
-
let diagnosticsListeners = [];
|
|
47
|
-
let diagnosticsResponses = [];
|
|
48
|
-
/**
|
|
49
|
-
* Get a promise that resolves when the next diagnostics event is emitted (or pop the earliest unhandled diagnostics list if some are already here)
|
|
50
|
-
*/
|
|
51
|
-
function onNextDiagnostics() {
|
|
52
|
-
if (diagnosticsResponses.length > 0) {
|
|
53
|
-
return Promise.resolve(diagnosticsResponses.shift());
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
return new Promise((resolve) => {
|
|
57
|
-
diagnosticsListeners.push(resolve);
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
async function setFile(srcPath, contents) {
|
|
62
|
-
//set the namespace first
|
|
63
|
-
await manager.handleFileChanges([{
|
|
64
|
-
srcPath: srcPath,
|
|
65
|
-
type: vscode_languageserver_protocol_1.FileChangeType.Changed,
|
|
66
|
-
fileContents: contents,
|
|
67
|
-
allowStandaloneProject: false
|
|
68
|
-
}]);
|
|
69
|
-
}
|
|
70
|
-
describe('on', () => {
|
|
71
|
-
it('emits events', async () => {
|
|
72
|
-
const stub = sinon.stub();
|
|
73
|
-
const off = manager.on('diagnostics', stub);
|
|
74
|
-
await manager['emit']('diagnostics', { project: undefined, diagnostics: [] });
|
|
75
|
-
(0, chai_1.expect)(stub.callCount).to.eql(1);
|
|
76
|
-
await manager['emit']('diagnostics', { project: undefined, diagnostics: [] });
|
|
77
|
-
(0, chai_1.expect)(stub.callCount).to.eql(2);
|
|
78
|
-
off();
|
|
79
|
-
await manager['emit']('diagnostics', { project: undefined, diagnostics: [] });
|
|
80
|
-
(0, chai_1.expect)(stub.callCount).to.eql(2);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
describe('validation tracking', () => {
|
|
84
|
-
it('tracks validation state', async () => {
|
|
85
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
86
|
-
const project = manager.projects[0];
|
|
87
|
-
//force validation to take a while
|
|
88
|
-
sinon.stub(project['builder'].program, 'validate').callsFake(async () => {
|
|
89
|
-
await util_1.default.sleep(100);
|
|
90
|
-
});
|
|
91
|
-
(0, chai_1.expect)(manager.busyStatusTracker.status).to.eql('idle');
|
|
92
|
-
//run several validations (which cancel the previous)
|
|
93
|
-
void project.validate();
|
|
94
|
-
await util_1.default.sleep(10);
|
|
95
|
-
void project.validate();
|
|
96
|
-
await util_1.default.sleep(10);
|
|
97
|
-
void project.validate();
|
|
98
|
-
await util_1.default.sleep(10);
|
|
99
|
-
//busy status should be active
|
|
100
|
-
(0, chai_1.expect)(manager.busyStatusTracker.status).to.eql('busy');
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
describe('syncProjects', () => {
|
|
104
|
-
it('does not crash on zero projects', async () => {
|
|
105
|
-
await manager.syncProjects([]);
|
|
106
|
-
});
|
|
107
|
-
it('finds bsconfig in a folder', async () => {
|
|
108
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, '');
|
|
109
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
110
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
111
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`
|
|
112
|
-
]);
|
|
113
|
-
});
|
|
114
|
-
it('finds bsconfig at root and also in subfolder', async () => {
|
|
115
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, '');
|
|
116
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/bsconfig.json`, '');
|
|
117
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
118
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
119
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`,
|
|
120
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir/bsconfig.json`
|
|
121
|
-
]);
|
|
122
|
-
});
|
|
123
|
-
it('skips excluded bsconfig bsconfig in a folder', async () => {
|
|
124
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, '');
|
|
125
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/bsconfig.json`, '');
|
|
126
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { excludePatterns: ['**/subdir/**/*'] })]);
|
|
127
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey)).to.eql([
|
|
128
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`
|
|
129
|
-
]);
|
|
130
|
-
});
|
|
131
|
-
it('uses rootDir when manifest found but no brightscript file', async () => {
|
|
132
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/manifest`, '');
|
|
133
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
134
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey)).to.eql([
|
|
135
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`
|
|
136
|
-
]);
|
|
137
|
-
});
|
|
138
|
-
it('returns root folder when automatic discovery is disabled', async () => {
|
|
139
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, '');
|
|
140
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project2/bsconfig.json`, '');
|
|
141
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { enableProjectDiscovery: false }) })]);
|
|
142
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey)).to.eql([
|
|
143
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`
|
|
144
|
-
]);
|
|
145
|
-
});
|
|
146
|
-
it('gets diagnostics from plugins added in afterProgramValidate', async () => {
|
|
147
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/plugin.js`, `
|
|
148
|
-
module.exports = function () {
|
|
149
|
-
return {
|
|
150
|
-
afterProgramValidate: function(program) {
|
|
151
|
-
var file = program.getFile('source/main.brs');
|
|
152
|
-
//add a diagnostic from a plugin
|
|
153
|
-
file.addDiagnostic({
|
|
154
|
-
message: 'Test diagnostic',
|
|
155
|
-
code: 'test-123',
|
|
156
|
-
severity: 1
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
`);
|
|
162
|
-
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
163
|
-
plugins: [
|
|
164
|
-
'./plugin.js'
|
|
165
|
-
]
|
|
166
|
-
});
|
|
167
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, `
|
|
168
|
-
sub test()
|
|
169
|
-
print nameNotDefined
|
|
170
|
-
end sub
|
|
171
|
-
`);
|
|
172
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/manifest`, '');
|
|
173
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
174
|
-
(0, testHelpers_spec_1.expectDiagnostics)(await onNextDiagnostics(), [
|
|
175
|
-
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('nameNotDefined').message,
|
|
176
|
-
'Test diagnostic'
|
|
177
|
-
]);
|
|
178
|
-
});
|
|
179
|
-
it('uses subdir when manifest and brightscript file found', async () => {
|
|
180
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/manifest`, '');
|
|
181
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/source/main.brs`, '');
|
|
182
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
183
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey)).to.eql([
|
|
184
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir`
|
|
185
|
-
]);
|
|
186
|
-
});
|
|
187
|
-
it('removes stale projects', async () => {
|
|
188
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`, '');
|
|
189
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`, '');
|
|
190
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
191
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
192
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`,
|
|
193
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`
|
|
194
|
-
]);
|
|
195
|
-
fsExtra.removeSync(`${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`);
|
|
196
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
197
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
198
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`
|
|
199
|
-
]);
|
|
200
|
-
});
|
|
201
|
-
it('keeps existing projects on subsequent sync calls', async () => {
|
|
202
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`, '');
|
|
203
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`, '');
|
|
204
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
205
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
206
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`,
|
|
207
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`
|
|
208
|
-
]);
|
|
209
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
210
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
211
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`,
|
|
212
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`
|
|
213
|
-
]);
|
|
214
|
-
});
|
|
215
|
-
it('uses nonstandard json naming when specified in projects array', async () => {
|
|
216
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project1/testBrighterScriptConfig.json`, '');
|
|
217
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, '');
|
|
218
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { projects: [
|
|
219
|
-
{ path: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/testBrighterScriptConfig.json` }
|
|
220
|
-
] })]);
|
|
221
|
-
//we should NOT have found the `project1/bsconfig.json` file because it's not in the projects array
|
|
222
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey)).to.eql([
|
|
223
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/testBrighterScriptConfig.json`
|
|
224
|
-
]);
|
|
225
|
-
});
|
|
226
|
-
it('supports pointing to a folder AND a bsconfig.json in projects array', async () => {
|
|
227
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project1/testBrighterScriptConfig.json`, '');
|
|
228
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { projects: [
|
|
229
|
-
{ path: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/testBrighterScriptConfig.json` },
|
|
230
|
-
{ path: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1` }
|
|
231
|
-
] })]);
|
|
232
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
233
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1`,
|
|
234
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/testBrighterScriptConfig.json`
|
|
235
|
-
]);
|
|
236
|
-
});
|
|
237
|
-
it('supports project with AND without bsconfig.json in same location in projects array', async () => {
|
|
238
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, '');
|
|
239
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { projects: [
|
|
240
|
-
{ path: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1` },
|
|
241
|
-
{ path: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/bsconfig.json` }
|
|
242
|
-
] })]);
|
|
243
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
244
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1`,
|
|
245
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/bsconfig.json`
|
|
246
|
-
]);
|
|
247
|
-
});
|
|
248
|
-
it('ignores empty projects array configuration', async () => {
|
|
249
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, '');
|
|
250
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { projects: [] })]);
|
|
251
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
252
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/project1/bsconfig.json`
|
|
253
|
-
]);
|
|
254
|
-
});
|
|
255
|
-
describe('concurrency limiting', () => {
|
|
256
|
-
it('limits the number of projects activating concurrently', async () => {
|
|
257
|
-
//create multiple bsconfig.json files
|
|
258
|
-
for (let i = 0; i < 6; i++) {
|
|
259
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project${i}/bsconfig.json`, '');
|
|
260
|
-
}
|
|
261
|
-
//track concurrent activation count by stubbing the private activateProject method
|
|
262
|
-
let maxConcurrent = 0;
|
|
263
|
-
let currentConcurrent = 0;
|
|
264
|
-
const activateStub = sinon.stub(manager, 'activateProject').callsFake(async () => {
|
|
265
|
-
currentConcurrent++;
|
|
266
|
-
maxConcurrent = Math.max(maxConcurrent, currentConcurrent);
|
|
267
|
-
//simulate async activation work
|
|
268
|
-
await util_1.default.sleep(10);
|
|
269
|
-
currentConcurrent--;
|
|
270
|
-
});
|
|
271
|
-
//set a low concurrency limit for testing
|
|
272
|
-
manager.projectActivationConcurrencyLimit = 2;
|
|
273
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
274
|
-
//should have activated all 6 projects
|
|
275
|
-
(0, chai_1.expect)(activateStub.callCount).to.eql(6);
|
|
276
|
-
//but never more than 2 at a time
|
|
277
|
-
(0, chai_1.expect)(maxConcurrent).to.be.at.most(2);
|
|
278
|
-
});
|
|
279
|
-
it('activates all projects even with concurrency limit', async () => {
|
|
280
|
-
//create 5 bsconfig.json files
|
|
281
|
-
for (let i = 0; i < 5; i++) {
|
|
282
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project${i}/bsconfig.json`, '');
|
|
283
|
-
}
|
|
284
|
-
manager.projectActivationConcurrencyLimit = 2;
|
|
285
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
286
|
-
//all projects should be created
|
|
287
|
-
(0, chai_1.expect)(manager.projects.length).to.eql(5);
|
|
288
|
-
});
|
|
289
|
-
it('limits the number of projects validating concurrently', async () => {
|
|
290
|
-
for (let i = 0; i < 6; i++) {
|
|
291
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project${i}/bsconfig.json`, '');
|
|
292
|
-
}
|
|
293
|
-
let maxConcurrent = 0;
|
|
294
|
-
let currentConcurrent = 0;
|
|
295
|
-
let validateCallCount = 0;
|
|
296
|
-
//stub activateProject to be a no-op so projects activate quickly
|
|
297
|
-
sinon.stub(manager, 'activateProject').callsFake(async () => { });
|
|
298
|
-
//stub Project.prototype.validate BEFORE syncProjects so the fire-and-forget phase uses it
|
|
299
|
-
sinon.stub(Project_1.Project.prototype, 'validate').callsFake(async () => {
|
|
300
|
-
currentConcurrent++;
|
|
301
|
-
validateCallCount++;
|
|
302
|
-
maxConcurrent = Math.max(maxConcurrent, currentConcurrent);
|
|
303
|
-
await util_1.default.sleep(10);
|
|
304
|
-
currentConcurrent--;
|
|
305
|
-
});
|
|
306
|
-
manager.projectActivationConcurrencyLimit = 2;
|
|
307
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
308
|
-
//wait for the fire-and-forget validation phase to complete
|
|
309
|
-
await util_1.default.sleep(200);
|
|
310
|
-
(0, chai_1.expect)(validateCallCount).to.eql(6);
|
|
311
|
-
(0, chai_1.expect)(maxConcurrent).to.be.at.most(2);
|
|
312
|
-
});
|
|
313
|
-
it('validates all projects after activation completes', async () => {
|
|
314
|
-
for (let i = 0; i < 3; i++) {
|
|
315
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project${i}/bsconfig.json`, '');
|
|
316
|
-
}
|
|
317
|
-
let allActivated = false;
|
|
318
|
-
let validationStartedBeforeActivation = false;
|
|
319
|
-
let validateCallCount = 0;
|
|
320
|
-
sinon.stub(manager, 'activateProject').callsFake(async () => { });
|
|
321
|
-
sinon.stub(Project_1.Project.prototype, 'validate').callsFake(() => {
|
|
322
|
-
if (!allActivated) {
|
|
323
|
-
validationStartedBeforeActivation = true;
|
|
324
|
-
}
|
|
325
|
-
validateCallCount++;
|
|
326
|
-
return Promise.resolve();
|
|
327
|
-
});
|
|
328
|
-
manager.projectActivationConcurrencyLimit = 1;
|
|
329
|
-
//hook into the end of the activation phase by spying on firstSync
|
|
330
|
-
const origTryResolve = manager['firstSync'].tryResolve.bind(manager['firstSync']);
|
|
331
|
-
sinon.stub(manager['firstSync'], 'tryResolve').callsFake(() => {
|
|
332
|
-
allActivated = true;
|
|
333
|
-
return origTryResolve();
|
|
334
|
-
});
|
|
335
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
336
|
-
//wait for fire-and-forget validation phase
|
|
337
|
-
await util_1.default.sleep(100);
|
|
338
|
-
(0, chai_1.expect)(validateCallCount).to.eql(3);
|
|
339
|
-
(0, chai_1.expect)(validationStartedBeforeActivation).to.be.false;
|
|
340
|
-
});
|
|
341
|
-
it('stops activating projects when a new sync starts', async () => {
|
|
342
|
-
for (let i = 0; i < 4; i++) {
|
|
343
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project${i}/bsconfig.json`, '');
|
|
344
|
-
}
|
|
345
|
-
let activateCount = 0;
|
|
346
|
-
const activateDeferred = new deferred_1.Deferred();
|
|
347
|
-
sinon.stub(manager, 'activateProject').callsFake(async () => {
|
|
348
|
-
activateCount++;
|
|
349
|
-
//block the first activation so we can trigger a re-sync
|
|
350
|
-
if (activateCount === 1) {
|
|
351
|
-
await activateDeferred.promise;
|
|
352
|
-
}
|
|
353
|
-
});
|
|
354
|
-
manager.projectActivationConcurrencyLimit = 1;
|
|
355
|
-
//start first sync (will block on first activation)
|
|
356
|
-
const firstSync = manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
357
|
-
//wait for the first activation to start
|
|
358
|
-
await util_1.default.sleep(50);
|
|
359
|
-
//start a second sync which bumps the generation counter
|
|
360
|
-
const secondSync = manager.syncProjects([testHelpers_spec_1.workspaceSettings], true);
|
|
361
|
-
//unblock the first activation
|
|
362
|
-
activateDeferred.resolve();
|
|
363
|
-
await firstSync;
|
|
364
|
-
await secondSync;
|
|
365
|
-
//the first sync should have stopped activating after generation changed.
|
|
366
|
-
//the exact count depends on timing, but we should NOT see all 4 from the first sync
|
|
367
|
-
//plus all 4 from the second sync (8 total). The first sync's remaining items should be skipped.
|
|
368
|
-
(0, chai_1.expect)(activateCount).to.be.lessThan(8);
|
|
369
|
-
});
|
|
370
|
-
it('skips validation when a new sync starts before validation phase', async () => {
|
|
371
|
-
for (let i = 0; i < 3; i++) {
|
|
372
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/project${i}/bsconfig.json`, '');
|
|
373
|
-
}
|
|
374
|
-
let validateCallCount = 0;
|
|
375
|
-
const activateDeferred = new deferred_1.Deferred();
|
|
376
|
-
sinon.stub(manager, 'activateProject').callsFake(async () => {
|
|
377
|
-
//block on the deferred only when it's pending (we'll make it pending for the second sync)
|
|
378
|
-
if (!activateDeferred.isCompleted) {
|
|
379
|
-
await activateDeferred.promise;
|
|
380
|
-
}
|
|
381
|
-
});
|
|
382
|
-
sinon.stub(Project_1.Project.prototype, 'validate').callsFake(() => {
|
|
383
|
-
validateCallCount++;
|
|
384
|
-
return Promise.resolve();
|
|
385
|
-
});
|
|
386
|
-
manager.projectActivationConcurrencyLimit = 1;
|
|
387
|
-
//first sync — activates and validates normally (deferred starts resolved)
|
|
388
|
-
activateDeferred.resolve();
|
|
389
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
390
|
-
await util_1.default.sleep(50);
|
|
391
|
-
const firstSyncValidateCount = validateCallCount;
|
|
392
|
-
//reset for the next syncs: create a new deferred that blocks
|
|
393
|
-
const blockDeferred = new deferred_1.Deferred();
|
|
394
|
-
manager.activateProject.callsFake(async () => {
|
|
395
|
-
await blockDeferred.promise;
|
|
396
|
-
});
|
|
397
|
-
//start second sync (blocks on activation)
|
|
398
|
-
const secondSync = manager.syncProjects([testHelpers_spec_1.workspaceSettings], true);
|
|
399
|
-
await util_1.default.sleep(10);
|
|
400
|
-
//immediately start a third sync which bumps the generation
|
|
401
|
-
const thirdSync = manager.syncProjects([testHelpers_spec_1.workspaceSettings], true);
|
|
402
|
-
//unblock activation
|
|
403
|
-
blockDeferred.resolve();
|
|
404
|
-
await secondSync;
|
|
405
|
-
await thirdSync;
|
|
406
|
-
//wait for any fire-and-forget validation
|
|
407
|
-
await util_1.default.sleep(100);
|
|
408
|
-
//the second sync's validation should have been skipped because the third sync bumped the generation.
|
|
409
|
-
//we should see at most the first sync's validations + the third sync's validations
|
|
410
|
-
(0, chai_1.expect)(validateCallCount - firstSyncValidateCount).to.be.at.most(3);
|
|
411
|
-
});
|
|
412
|
-
});
|
|
413
|
-
});
|
|
414
|
-
describe('maxDepth configuration', () => {
|
|
415
|
-
function writeTestFiles(files) {
|
|
416
|
-
for (const [filePath, content] of Object.entries(files)) {
|
|
417
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/${filePath}`, content);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
it('respects maxDepth of 1 when discovering projects', async () => {
|
|
421
|
-
// Create bsconfig.json files at different depths
|
|
422
|
-
writeTestFiles({
|
|
423
|
-
'bsconfig.json': '',
|
|
424
|
-
'level1/bsconfig.json': '',
|
|
425
|
-
'level1/level2/bsconfig.json': '',
|
|
426
|
-
'level1/level2/level3/bsconfig.json': ''
|
|
427
|
-
});
|
|
428
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { projectDiscoveryMaxDepth: 1 }) })]);
|
|
429
|
-
// maxDepth: 1 should find files at depth 0 only
|
|
430
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
431
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`
|
|
432
|
-
]);
|
|
433
|
-
});
|
|
434
|
-
it('respects maxDepth of 5 when discovering projects', async () => {
|
|
435
|
-
// Create bsconfig.json files at different depths
|
|
436
|
-
writeTestFiles({
|
|
437
|
-
'bsconfig.json': '',
|
|
438
|
-
'level1/bsconfig.json': '',
|
|
439
|
-
'level1/level2/bsconfig.json': '',
|
|
440
|
-
'level1/level2/level3/bsconfig.json': '',
|
|
441
|
-
'level1/level2/level3/level4/bsconfig.json': '',
|
|
442
|
-
'level1/level2/level3/level4/level5/bsconfig.json': '',
|
|
443
|
-
'level1/level2/level3/level4/level5/level6/bsconfig.json': ''
|
|
444
|
-
});
|
|
445
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { projectDiscoveryMaxDepth: 5 }) })]);
|
|
446
|
-
// maxDepth: 5 should find files at depths 0, 1, 2, 3, 4
|
|
447
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
448
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`,
|
|
449
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/bsconfig.json`,
|
|
450
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/bsconfig.json`,
|
|
451
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/bsconfig.json`,
|
|
452
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/level4/bsconfig.json`
|
|
453
|
-
]);
|
|
454
|
-
});
|
|
455
|
-
it('respects maxDepth of 20 when discovering projects', async () => {
|
|
456
|
-
// Create bsconfig.json files at different depths, skipping some levels in between
|
|
457
|
-
// and proving it stops at level 20 by creating files at level 20 and 21
|
|
458
|
-
// Note: depth 20 means the file is in the 20th directory level from root
|
|
459
|
-
writeTestFiles({
|
|
460
|
-
'bsconfig.json': '',
|
|
461
|
-
'level1/bsconfig.json': '',
|
|
462
|
-
'level1/level2/level3/level4/level5/bsconfig.json': '',
|
|
463
|
-
'level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/level11/level12/level13/level14/level15/level16/level17/level18/level19/bsconfig.json': '',
|
|
464
|
-
'level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/level11/level12/level13/level14/level15/level16/level17/level18/level19/level20/bsconfig.json': ''
|
|
465
|
-
});
|
|
466
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { projectDiscoveryMaxDepth: 20 }) })]);
|
|
467
|
-
// maxDepth: 20 should find file at level 19 (depth 20) but not at level 20 (depth 21)
|
|
468
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
469
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`,
|
|
470
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/bsconfig.json`,
|
|
471
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/level4/level5/bsconfig.json`,
|
|
472
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/level11/level12/level13/level14/level15/level16/level17/level18/level19/bsconfig.json`
|
|
473
|
-
]);
|
|
474
|
-
});
|
|
475
|
-
it('uses default maxDepth of 15 when no maxDepth is specified', async () => {
|
|
476
|
-
// Create bsconfig.json files at different depths, skipping some levels in between
|
|
477
|
-
// and proving it stops at level 15 by creating files at level 15 and 16
|
|
478
|
-
// Note: depth 15 means the file is in the 15th directory level from root
|
|
479
|
-
writeTestFiles({
|
|
480
|
-
'bsconfig.json': '',
|
|
481
|
-
'level1/bsconfig.json': '',
|
|
482
|
-
'level1/level2/level3/level4/level5/bsconfig.json': '',
|
|
483
|
-
'level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/level11/level12/level13/level14/bsconfig.json': '',
|
|
484
|
-
'level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/level11/level12/level13/level14/level15/bsconfig.json': ''
|
|
485
|
-
});
|
|
486
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
487
|
-
// Default maxDepth: 15 should find file at level 14 (depth 15) but not at level 15 (depth 16)
|
|
488
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
489
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/bsconfig.json`,
|
|
490
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/bsconfig.json`,
|
|
491
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/level4/level5/bsconfig.json`,
|
|
492
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/level4/level5/level6/level7/level8/level9/level10/level11/level12/level13/level14/bsconfig.json`
|
|
493
|
-
]);
|
|
494
|
-
});
|
|
495
|
-
it('respects maxDepth of 1 when discovering roku projects with manifest files', async () => {
|
|
496
|
-
// Create manifest files at different depths
|
|
497
|
-
writeTestFiles({
|
|
498
|
-
'manifest': '',
|
|
499
|
-
'source/main.brs': '',
|
|
500
|
-
'level1/manifest': '',
|
|
501
|
-
'level1/source/main.brs': '',
|
|
502
|
-
'level1/level2/manifest': '',
|
|
503
|
-
'level1/level2/source/main.brs': '',
|
|
504
|
-
'level1/level2/level3/manifest': '',
|
|
505
|
-
'level1/level2/level3/source/main.brs': ''
|
|
506
|
-
});
|
|
507
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { projectDiscoveryMaxDepth: 1 }) })]);
|
|
508
|
-
// maxDepth: 1 should find projects at depth 0 only
|
|
509
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
510
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`
|
|
511
|
-
]);
|
|
512
|
-
});
|
|
513
|
-
it('respects maxDepth of 5 when discovering roku projects with manifest files', async () => {
|
|
514
|
-
// Create manifest files at different depths
|
|
515
|
-
writeTestFiles({
|
|
516
|
-
'manifest': '',
|
|
517
|
-
'source/main.brs': '',
|
|
518
|
-
'level1/manifest': '',
|
|
519
|
-
'level1/source/main.brs': '',
|
|
520
|
-
'level1/level2/manifest': '',
|
|
521
|
-
'level1/level2/source/main.brs': '',
|
|
522
|
-
'level1/level2/level3/manifest': '',
|
|
523
|
-
'level1/level2/level3/source/main.brs': '',
|
|
524
|
-
'level1/level2/level3/level4/manifest': '',
|
|
525
|
-
'level1/level2/level3/level4/source/main.brs': '',
|
|
526
|
-
'level1/level2/level3/level4/level5/manifest': '',
|
|
527
|
-
'level1/level2/level3/level4/level5/source/main.brs': '',
|
|
528
|
-
'level1/level2/level3/level4/level5/level6/manifest': '',
|
|
529
|
-
'level1/level2/level3/level4/level5/level6/source/main.brs': ''
|
|
530
|
-
});
|
|
531
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { projectDiscoveryMaxDepth: 5 }) })]);
|
|
532
|
-
// maxDepth: 5 should find projects at depths 0, 1, 2, 3, 4
|
|
533
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey).sort()).to.eql([
|
|
534
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`,
|
|
535
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1`,
|
|
536
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2`,
|
|
537
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3`,
|
|
538
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/level1/level2/level3/level4`
|
|
539
|
-
]);
|
|
540
|
-
});
|
|
541
|
-
});
|
|
542
|
-
describe('getCompletions', () => {
|
|
543
|
-
it('works for quick file changes', async () => {
|
|
544
|
-
//set up the project
|
|
545
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
546
|
-
//add the namespace first
|
|
547
|
-
await setFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/alpha.bs`, `
|
|
548
|
-
namespace alpha
|
|
549
|
-
enum Direction
|
|
550
|
-
up
|
|
551
|
-
end enum
|
|
552
|
-
end namespace
|
|
553
|
-
`);
|
|
554
|
-
//add the baseline file
|
|
555
|
-
await setFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`, `
|
|
556
|
-
sub test()
|
|
557
|
-
thing = alpha.Directio
|
|
558
|
-
end sub
|
|
559
|
-
`);
|
|
560
|
-
await manager.onIdle();
|
|
561
|
-
//now for the test. type a char, request completions, type a char, request completions (just like how vscode does it)
|
|
562
|
-
void setFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`, `
|
|
563
|
-
sub test()
|
|
564
|
-
thing = alpha.Direction
|
|
565
|
-
end sub
|
|
566
|
-
`);
|
|
567
|
-
// const completionsPromise1 = manager.getCompletions({
|
|
568
|
-
// srcPath: s`${rootDir}/source/main.bs`,
|
|
569
|
-
// position: util.createPosition(2, 43)
|
|
570
|
-
// });
|
|
571
|
-
//request completions
|
|
572
|
-
void setFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`, `
|
|
573
|
-
sub test()
|
|
574
|
-
thing = alpha.Direction.
|
|
575
|
-
end sub
|
|
576
|
-
`);
|
|
577
|
-
const completionsPromise2 = manager.getCompletions({
|
|
578
|
-
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`,
|
|
579
|
-
position: util_1.default.createPosition(2, 44)
|
|
580
|
-
});
|
|
581
|
-
// //the first set of completions should only have the `alpha.Direction` enum
|
|
582
|
-
// expectCompletionsIncludes(await completionsPromise1, [{
|
|
583
|
-
// label: 'Direction'
|
|
584
|
-
// }]);
|
|
585
|
-
//the next set of completions should only have the alpha.Direction.up enum member
|
|
586
|
-
(0, testHelpers_spec_1.expectCompletionsIncludes)(await completionsPromise2, [{
|
|
587
|
-
label: 'up'
|
|
588
|
-
}]);
|
|
589
|
-
});
|
|
590
|
-
});
|
|
591
|
-
describe('getFileRenameEdits', () => {
|
|
592
|
-
const mainUri = util_1.default.pathToUri((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`);
|
|
593
|
-
function fakeProject(getFileRenameEdits) {
|
|
594
|
-
return {
|
|
595
|
-
projectNumber: 0,
|
|
596
|
-
whenActivated: () => Promise.resolve(),
|
|
597
|
-
getFileRenameEdits: getFileRenameEdits
|
|
598
|
-
};
|
|
599
|
-
}
|
|
600
|
-
function fileRenameEdit(uri, newText, range = util_1.default.createRange(0, 8, 0, 14)) {
|
|
601
|
-
return { uri: uri, range: range, newText: newText };
|
|
602
|
-
}
|
|
603
|
-
beforeEach(() => {
|
|
604
|
-
//these tests exercise the cross-project consensus logic; bypass the project-sync wait so we don't need a real project setup
|
|
605
|
-
sinon.stub(manager, 'onIdle').callsFake(() => Promise.resolve());
|
|
606
|
-
});
|
|
607
|
-
it('passes through edits from a single project', async () => {
|
|
608
|
-
manager.projects = [
|
|
609
|
-
fakeProject(() => [fileRenameEdit(mainUri, 'lib2.bs')])
|
|
610
|
-
];
|
|
611
|
-
const result = await manager.getFileRenameEdits({
|
|
612
|
-
oldSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib.bs`,
|
|
613
|
-
newSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2.bs`
|
|
614
|
-
});
|
|
615
|
-
(0, chai_1.expect)(result).to.have.lengthOf(1);
|
|
616
|
-
(0, chai_1.expect)(result[0].uri).to.eql(mainUri);
|
|
617
|
-
(0, chai_1.expect)(result[0].newText).to.eql('lib2.bs');
|
|
618
|
-
});
|
|
619
|
-
it('keeps edits when every project that produced an edit at the same range agrees', async () => {
|
|
620
|
-
manager.projects = [
|
|
621
|
-
fakeProject(() => [fileRenameEdit(mainUri, 'lib2.bs')]),
|
|
622
|
-
fakeProject(() => [fileRenameEdit(mainUri, 'lib2.bs')])
|
|
623
|
-
];
|
|
624
|
-
const result = await manager.getFileRenameEdits({
|
|
625
|
-
oldSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib.bs`,
|
|
626
|
-
newSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2.bs`
|
|
627
|
-
});
|
|
628
|
-
(0, chai_1.expect)(result).to.have.lengthOf(1);
|
|
629
|
-
(0, chai_1.expect)(result[0].newText).to.eql('lib2.bs');
|
|
630
|
-
});
|
|
631
|
-
it('drops edits when projects disagree on the replacement text for the same range', async () => {
|
|
632
|
-
manager.projects = [
|
|
633
|
-
fakeProject(() => [fileRenameEdit(mainUri, 'lib2.bs')]),
|
|
634
|
-
fakeProject(() => [fileRenameEdit(mainUri, 'pkg:/source/lib2.bs')])
|
|
635
|
-
];
|
|
636
|
-
const result = await manager.getFileRenameEdits({
|
|
637
|
-
oldSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib.bs`,
|
|
638
|
-
newSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2.bs`
|
|
639
|
-
});
|
|
640
|
-
(0, chai_1.expect)(result).to.be.empty;
|
|
641
|
-
});
|
|
642
|
-
it('keeps edits unique to one project when others have nothing to say at that range', async () => {
|
|
643
|
-
manager.projects = [
|
|
644
|
-
fakeProject(() => [fileRenameEdit(mainUri, 'lib2.bs')]),
|
|
645
|
-
fakeProject(() => [])
|
|
646
|
-
];
|
|
647
|
-
const result = await manager.getFileRenameEdits({
|
|
648
|
-
oldSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib.bs`,
|
|
649
|
-
newSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2.bs`
|
|
650
|
-
});
|
|
651
|
-
(0, chai_1.expect)(result).to.have.lengthOf(1);
|
|
652
|
-
});
|
|
653
|
-
it('still emits edits from healthy projects when one project throws', async () => {
|
|
654
|
-
manager.projects = [
|
|
655
|
-
fakeProject(() => {
|
|
656
|
-
throw new Error('boom');
|
|
657
|
-
}),
|
|
658
|
-
fakeProject(() => [fileRenameEdit(mainUri, 'lib2.bs')])
|
|
659
|
-
];
|
|
660
|
-
const result = await manager.getFileRenameEdits({
|
|
661
|
-
oldSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib.bs`,
|
|
662
|
-
newSrcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2.bs`
|
|
663
|
-
});
|
|
664
|
-
(0, chai_1.expect)(result).to.have.lengthOf(1);
|
|
665
|
-
(0, chai_1.expect)(result[0].newText).to.eql('lib2.bs');
|
|
666
|
-
});
|
|
667
|
-
});
|
|
668
|
-
describe('flushDocumentChanges', () => {
|
|
669
|
-
it('reuses cached PathCollection across multiple flushes', async () => {
|
|
670
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, ``);
|
|
671
|
-
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {});
|
|
672
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
673
|
-
//spy on PathCollection constructor to count how many are created
|
|
674
|
-
const project = manager.projects[0];
|
|
675
|
-
//first flush to warm the cache
|
|
676
|
-
await manager['flushDocumentChanges']({
|
|
677
|
-
actions: [{
|
|
678
|
-
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`,
|
|
679
|
-
type: 'set',
|
|
680
|
-
fileContents: 'sub main():end sub',
|
|
681
|
-
allowStandaloneProject: true
|
|
682
|
-
}]
|
|
683
|
-
});
|
|
684
|
-
//grab the cached filterer
|
|
685
|
-
const cachedFilterer = manager['projectFiltererCache'].get(project);
|
|
686
|
-
(0, chai_1.expect)(cachedFilterer).to.exist;
|
|
687
|
-
//second flush should reuse the same filterer instance
|
|
688
|
-
await manager['flushDocumentChanges']({
|
|
689
|
-
actions: [{
|
|
690
|
-
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`,
|
|
691
|
-
type: 'set',
|
|
692
|
-
fileContents: 'sub main2():end sub',
|
|
693
|
-
allowStandaloneProject: true
|
|
694
|
-
}]
|
|
695
|
-
});
|
|
696
|
-
const cachedFilterer2 = manager['projectFiltererCache'].get(project);
|
|
697
|
-
(0, chai_1.expect)(cachedFilterer2).to.equal(cachedFilterer);
|
|
698
|
-
});
|
|
699
|
-
it('does not crash when getting undefined back from projects', async () => {
|
|
700
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, ``);
|
|
701
|
-
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, {
|
|
702
|
-
rootDir: testHelpers_spec_1.rootDir
|
|
703
|
-
});
|
|
704
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
705
|
-
sinon.stub(manager.projects[0], 'applyFileChanges').returns(Promise.resolve([
|
|
706
|
-
//return an undefined item, which used to cause a specific crash
|
|
707
|
-
undefined
|
|
708
|
-
]));
|
|
709
|
-
await manager['flushDocumentChanges']({
|
|
710
|
-
actions: [{
|
|
711
|
-
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`,
|
|
712
|
-
type: 'set',
|
|
713
|
-
fileContents: 'sub main():end sub',
|
|
714
|
-
allowStandaloneProject: true
|
|
715
|
-
}]
|
|
716
|
-
});
|
|
717
|
-
});
|
|
718
|
-
});
|
|
719
|
-
describe('handleFileChanges', () => {
|
|
720
|
-
it('only sends files to the project that match the include patterns for that project', async () => {
|
|
721
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib1/a.brs`, ``);
|
|
722
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib2/a.brs`, ``);
|
|
723
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib1/b.brs`, ``);
|
|
724
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib2/b.brs`, ``);
|
|
725
|
-
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, {
|
|
726
|
-
rootDir: testHelpers_spec_1.rootDir,
|
|
727
|
-
files: [
|
|
728
|
-
'source/**/a.brs'
|
|
729
|
-
]
|
|
730
|
-
});
|
|
731
|
-
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/project2/bsconfig.json`, {
|
|
732
|
-
rootDir: testHelpers_spec_1.rootDir,
|
|
733
|
-
files: [
|
|
734
|
-
'source/**/b.brs'
|
|
735
|
-
]
|
|
736
|
-
});
|
|
737
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
738
|
-
let deferred1 = new deferred_1.Deferred();
|
|
739
|
-
let deferred2 = new deferred_1.Deferred();
|
|
740
|
-
const project1 = manager.projects.find(x => x.bsconfigPath.includes('project1'));
|
|
741
|
-
const project2 = manager.projects.find(x => x.bsconfigPath.includes('project2'));
|
|
742
|
-
const project1Stub = sinon.stub(project1, 'applyFileChanges').callsFake(async (...args) => {
|
|
743
|
-
const result = await project1Stub.wrappedMethod.apply(project1, args);
|
|
744
|
-
deferred1.resolve();
|
|
745
|
-
return result;
|
|
746
|
-
});
|
|
747
|
-
const project2Stub = sinon.stub(project2, 'applyFileChanges').callsFake(async (...args) => {
|
|
748
|
-
const result = await project2Stub.wrappedMethod.apply(project1, args);
|
|
749
|
-
deferred2.resolve();
|
|
750
|
-
return result;
|
|
751
|
-
});
|
|
752
|
-
await manager.handleFileChanges([
|
|
753
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib1/a.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
|
|
754
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib2/a.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
|
|
755
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib1/b.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
|
|
756
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib2/b.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed }
|
|
757
|
-
]);
|
|
758
|
-
//wait for the functions to finish being called
|
|
759
|
-
await Promise.all([
|
|
760
|
-
deferred1.promise,
|
|
761
|
-
deferred2.promise
|
|
762
|
-
]);
|
|
763
|
-
//project1 should only receive a.brs files
|
|
764
|
-
(0, chai_1.expect)(project1Stub.getCall(0).args[0].map(x => x.srcPath)).to.eql([
|
|
765
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib1/a.brs`,
|
|
766
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2/a.brs`
|
|
767
|
-
]);
|
|
768
|
-
//project2 should only receive b.brs files
|
|
769
|
-
(0, chai_1.expect)(project2Stub.getCall(0).args[0].map(x => x.srcPath)).to.eql([
|
|
770
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib1/b.brs`,
|
|
771
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2/b.brs`
|
|
772
|
-
]);
|
|
773
|
-
});
|
|
774
|
-
it('excludes files based on global exclude patterns', async () => {
|
|
775
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/file1.md`, ``);
|
|
776
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/file2.brs`, ``);
|
|
777
|
-
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
778
|
-
files: [
|
|
779
|
-
'source/**/*.brs'
|
|
780
|
-
]
|
|
781
|
-
});
|
|
782
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
783
|
-
const stub = sinon.stub(manager, 'handleFileChange').callThrough();
|
|
784
|
-
//register an exclusion filter
|
|
785
|
-
pathFilterer.registerExcludeList(testHelpers_spec_1.rootDir, [
|
|
786
|
-
'**/*.md'
|
|
787
|
-
]);
|
|
788
|
-
//make sure the .md file is ignored
|
|
789
|
-
await manager.handleFileChanges([
|
|
790
|
-
{ srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file1.md`, type: vscode_languageserver_protocol_1.FileChangeType.Created },
|
|
791
|
-
{ srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Created }
|
|
792
|
-
]);
|
|
793
|
-
await manager.onIdle();
|
|
794
|
-
(0, chai_1.expect)(stub.getCalls().map(x => x.args[0]).map(x => x.srcPath)).to.eql([
|
|
795
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`
|
|
796
|
-
]);
|
|
797
|
-
stub.reset();
|
|
798
|
-
//remove all filters, make sure the markdown file is included
|
|
799
|
-
pathFilterer.clear();
|
|
800
|
-
await manager.handleFileChanges([
|
|
801
|
-
{ srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file1.md`, type: vscode_languageserver_protocol_1.FileChangeType.Created },
|
|
802
|
-
{ srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Created }
|
|
803
|
-
]);
|
|
804
|
-
await manager.onIdle();
|
|
805
|
-
(0, chai_1.expect)(stub.getCalls().flatMap(x => x.args[0]).map(x => x.srcPath)).to.eql([
|
|
806
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file1.md`,
|
|
807
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`
|
|
808
|
-
]);
|
|
809
|
-
});
|
|
810
|
-
it('keeps files from bsconfig.json even if the path matches an exclude list', async () => {
|
|
811
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/file1.md`, ``);
|
|
812
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/file2.brs`, ``);
|
|
813
|
-
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
814
|
-
files: ['source/**/*']
|
|
815
|
-
});
|
|
816
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
817
|
-
const stub = sinon.stub(manager['projects'][0], 'applyFileChanges').callThrough();
|
|
818
|
-
//register an exclusion filter
|
|
819
|
-
pathFilterer.registerExcludeList(testHelpers_spec_1.rootDir, [
|
|
820
|
-
'**/*.md'
|
|
821
|
-
]);
|
|
822
|
-
//make sure the .md file is included because of its project's files array
|
|
823
|
-
await manager.handleFileChanges([
|
|
824
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/file1.md`, type: vscode_languageserver_protocol_1.FileChangeType.Created },
|
|
825
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/file2.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Created }
|
|
826
|
-
]);
|
|
827
|
-
await manager.onIdle();
|
|
828
|
-
(0, chai_1.expect)(stub.getCalls().flatMap(x => x.args[0]).map(x => x.srcPath)).to.eql([
|
|
829
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file1.md`,
|
|
830
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`
|
|
831
|
-
]);
|
|
832
|
-
});
|
|
833
|
-
it('does not create a standalone project for files that exist in a known project', async () => {
|
|
834
|
-
fsExtra.outputFileSync((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`, `sub main() : end sub`);
|
|
835
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
836
|
-
await onNextDiagnostics();
|
|
837
|
-
await manager.handleFileChanges([
|
|
838
|
-
{ srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed, fileContents: `'test`, allowStandaloneProject: true }
|
|
839
|
-
]);
|
|
840
|
-
await onNextDiagnostics();
|
|
841
|
-
//there should NOT be a standalone project
|
|
842
|
-
(0, chai_1.expect)(manager['standaloneProjects'].size).to.eql(0);
|
|
843
|
-
});
|
|
844
|
-
it('converts a missing file to a delete', async () => {
|
|
845
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
846
|
-
await onNextDiagnostics();
|
|
847
|
-
let applyFileChangesDeferred = new deferred_1.Deferred();
|
|
848
|
-
const project1 = manager.projects[0];
|
|
849
|
-
const project1Stub = sinon.stub(project1, 'applyFileChanges').callsFake(async (...args) => {
|
|
850
|
-
const result = await project1Stub.wrappedMethod.apply(project1, args);
|
|
851
|
-
applyFileChangesDeferred.resolve(result);
|
|
852
|
-
return result;
|
|
853
|
-
});
|
|
854
|
-
//emit created and changed events for files that don't exist. These turn into delete events
|
|
855
|
-
await manager.handleFileChanges([
|
|
856
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/missing1.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Created },
|
|
857
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/missing2.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed }
|
|
858
|
-
]);
|
|
859
|
-
//wait for the next set of diagnostics to arrive (signifying the files have been applied)
|
|
860
|
-
const result = await applyFileChangesDeferred.promise;
|
|
861
|
-
//make sure the project has these files
|
|
862
|
-
(0, chai_1.expect)(result.map(x => {
|
|
863
|
-
return { type: x.type, srcPath: x.srcPath };
|
|
864
|
-
})).to.eql([{
|
|
865
|
-
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/missing1.brs`,
|
|
866
|
-
type: 'set'
|
|
867
|
-
}, {
|
|
868
|
-
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/missing2.brs`,
|
|
869
|
-
type: 'set'
|
|
870
|
-
}, {
|
|
871
|
-
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/missing1.brs`,
|
|
872
|
-
type: 'delete'
|
|
873
|
-
}, {
|
|
874
|
-
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/missing2.brs`,
|
|
875
|
-
type: 'delete'
|
|
876
|
-
}]);
|
|
877
|
-
});
|
|
878
|
-
it('properly syncs changes', async () => {
|
|
879
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib1.brs`, `sub test1():print "alpha":end sub`);
|
|
880
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib2.brs`, `sub test2():print "beta":end sub`);
|
|
881
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
882
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(await onNextDiagnostics());
|
|
883
|
-
await manager.handleFileChanges([
|
|
884
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib1.brs`, fileContents: `sub test1():print alpha:end sub`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
|
|
885
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib2.brs`, fileContents: `sub test2()::print beta:end sub`, type: vscode_languageserver_protocol_1.FileChangeType.Changed }
|
|
886
|
-
]);
|
|
887
|
-
(0, testHelpers_spec_1.expectDiagnostics)(await onNextDiagnostics(), [
|
|
888
|
-
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('alpha').message,
|
|
889
|
-
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('beta').message
|
|
890
|
-
]);
|
|
891
|
-
await manager.handleFileChanges([
|
|
892
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib1.brs`, fileContents: `sub test1():print "alpha":end sub`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
|
|
893
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib2.brs`, fileContents: `sub test2()::print "beta":end sub`, type: vscode_languageserver_protocol_1.FileChangeType.Changed }
|
|
894
|
-
]);
|
|
895
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(await onNextDiagnostics());
|
|
896
|
-
});
|
|
897
|
-
it('adds all new files in a folder', async () => {
|
|
898
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, `sub main():print "main":end sub`);
|
|
899
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
900
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(await onNextDiagnostics());
|
|
901
|
-
//add a few files to a folder, then register that folder as an "add"
|
|
902
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/alpha/beta.brs`, `sub beta(): print one: end sub`);
|
|
903
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/alpha/charlie/delta.brs`, `sub delta():print two:end sub`);
|
|
904
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/echo/foxtrot.brs`, `sub foxtrot():print three:end sub`);
|
|
905
|
-
await manager.handleFileChanges([
|
|
906
|
-
//register the entire folder as an "add"
|
|
907
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/libs`, type: vscode_languageserver_protocol_1.FileChangeType.Created }
|
|
908
|
-
]);
|
|
909
|
-
(0, testHelpers_spec_1.expectDiagnostics)(await onNextDiagnostics(), [
|
|
910
|
-
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('one').message,
|
|
911
|
-
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('two').message,
|
|
912
|
-
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('three').message
|
|
913
|
-
]);
|
|
914
|
-
});
|
|
915
|
-
it('removes all files in a folder', async () => {
|
|
916
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, `sub main():print "main":end sub`);
|
|
917
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/alpha/beta.brs`, `sub beta(): print one: end sub`);
|
|
918
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/alpha/charlie/delta.brs`, `sub delta():print two:end sub`);
|
|
919
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/echo/foxtrot.brs`, `sub foxtrot():print three:end sub`);
|
|
920
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
921
|
-
(0, testHelpers_spec_1.expectDiagnostics)(await onNextDiagnostics(), [
|
|
922
|
-
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('one').message,
|
|
923
|
-
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('two').message,
|
|
924
|
-
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('three').message
|
|
925
|
-
]);
|
|
926
|
-
await manager.handleFileChanges([
|
|
927
|
-
//register the entire folder as an "add"
|
|
928
|
-
{ srcPath: `${testHelpers_spec_1.rootDir}/source/libs`, type: vscode_languageserver_protocol_1.FileChangeType.Deleted }
|
|
929
|
-
]);
|
|
930
|
-
(0, testHelpers_spec_1.expectZeroDiagnostics)(await onNextDiagnostics());
|
|
931
|
-
});
|
|
932
|
-
});
|
|
933
|
-
describe('threading', () => {
|
|
934
|
-
before(async function workerThreadWarmup() {
|
|
935
|
-
this.timeout(60000);
|
|
936
|
-
await (0, WorkerThreadProject_spec_1.getWakeWorkerThreadPromise)();
|
|
937
|
-
});
|
|
938
|
-
it('spawns a worker thread when threading is enabled', async () => {
|
|
939
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { enableThreading: true }) })]);
|
|
940
|
-
(0, chai_1.expect)(manager.projects[0]).instanceof(WorkerThreadProject_1.WorkerThreadProject);
|
|
941
|
-
});
|
|
942
|
-
});
|
|
943
|
-
describe('getProject', () => {
|
|
944
|
-
it('uses .projectKey if param is not a string', async () => {
|
|
945
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
946
|
-
(0, chai_1.expect)(manager['getProject']({
|
|
947
|
-
projectKey: testHelpers_spec_1.rootDir
|
|
948
|
-
}).projectKey).to.eql(testHelpers_spec_1.rootDir);
|
|
949
|
-
});
|
|
950
|
-
});
|
|
951
|
-
describe('createAndActivateProject', () => {
|
|
952
|
-
it('skips creating project if we already have it', async () => {
|
|
953
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
954
|
-
await manager['createAndActivateProject']({
|
|
955
|
-
projectKey: testHelpers_spec_1.rootDir,
|
|
956
|
-
projectDir: testHelpers_spec_1.rootDir,
|
|
957
|
-
workspaceFolder: testHelpers_spec_1.rootDir,
|
|
958
|
-
bsconfigPath: undefined
|
|
959
|
-
});
|
|
960
|
-
(0, chai_1.expect)(manager.projects.map(x => x.projectKey)).to.eql([
|
|
961
|
-
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`
|
|
962
|
-
]);
|
|
963
|
-
});
|
|
964
|
-
it('uses given projectNumber', async () => {
|
|
965
|
-
await manager['createAndActivateProject']({
|
|
966
|
-
projectKey: testHelpers_spec_1.rootDir,
|
|
967
|
-
projectDir: testHelpers_spec_1.rootDir,
|
|
968
|
-
workspaceFolder: testHelpers_spec_1.rootDir,
|
|
969
|
-
bsconfigPath: undefined,
|
|
970
|
-
projectNumber: 3
|
|
971
|
-
});
|
|
972
|
-
(0, chai_1.expect)(manager.projects[0].projectNumber).to.eql(3);
|
|
973
|
-
});
|
|
974
|
-
it('properly tracks a failed run', async () => {
|
|
975
|
-
//force a total crash
|
|
976
|
-
sinon.stub(Project_1.Project.prototype, 'activate').returns(Promise.reject(new Error('Critical failure')));
|
|
977
|
-
let error;
|
|
978
|
-
try {
|
|
979
|
-
await manager['createAndActivateProject']({
|
|
980
|
-
projectKey: testHelpers_spec_1.rootDir,
|
|
981
|
-
projectDir: testHelpers_spec_1.rootDir,
|
|
982
|
-
workspaceFolder: testHelpers_spec_1.rootDir,
|
|
983
|
-
bsconfigPath: 'subdir1/brsconfig.json'
|
|
984
|
-
});
|
|
985
|
-
}
|
|
986
|
-
catch (e) {
|
|
987
|
-
error = e;
|
|
988
|
-
}
|
|
989
|
-
(0, chai_1.expect)(error).to.include({ message: 'Critical failure' });
|
|
990
|
-
});
|
|
991
|
-
});
|
|
992
|
-
describe('removeProject', () => {
|
|
993
|
-
it('handles undefined', async () => {
|
|
994
|
-
manager['removeProject'](undefined);
|
|
995
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
996
|
-
manager['removeProject'](undefined);
|
|
997
|
-
});
|
|
998
|
-
it('does not crash when removing project that is not there', () => {
|
|
999
|
-
manager['removeProject']({
|
|
1000
|
-
projectPath: testHelpers_spec_1.rootDir,
|
|
1001
|
-
dispose: () => { }
|
|
1002
|
-
});
|
|
1003
|
-
});
|
|
1004
|
-
});
|
|
1005
|
-
describe('getSemanticTokens', () => {
|
|
1006
|
-
it('waits until the project is ready', () => {
|
|
1007
|
-
});
|
|
1008
|
-
});
|
|
1009
|
-
describe('standalone projects', () => {
|
|
1010
|
-
it('creates a standalone project for files not found in a project', async () => {
|
|
1011
|
-
var _a;
|
|
1012
|
-
await manager.syncProjects([]);
|
|
1013
|
-
await manager.handleFileChanges([{
|
|
1014
|
-
srcPath: `${testHelpers_spec_1.rootDir}/source/main.brs`,
|
|
1015
|
-
type: vscode_languageserver_protocol_1.FileChangeType.Created,
|
|
1016
|
-
fileContents: `sub main():print "main":end sub`,
|
|
1017
|
-
allowStandaloneProject: true
|
|
1018
|
-
}]);
|
|
1019
|
-
await onNextDiagnostics();
|
|
1020
|
-
(0, chai_1.expect)((_a = [...manager['standaloneProjects'].values()][0]) === null || _a === void 0 ? void 0 : _a.srcPath).to.eql((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`);
|
|
1021
|
-
//it deletes the standalone project when the file is closed
|
|
1022
|
-
await manager.handleFileClose({
|
|
1023
|
-
srcPath: `${testHelpers_spec_1.rootDir}/source/main.brs`
|
|
1024
|
-
});
|
|
1025
|
-
(0, chai_1.expect)(manager['standaloneProjects'].size).to.eql(0);
|
|
1026
|
-
});
|
|
1027
|
-
});
|
|
1028
|
-
it('completes promise when project is disposed in the middle of a flow', async function () {
|
|
1029
|
-
this.timeout(20000);
|
|
1030
|
-
//small plugin to communicate over a socket inside the worker thread.
|
|
1031
|
-
//This transpiles from tsc use `require()` for all imports and don't reference external vars
|
|
1032
|
-
class Plugin {
|
|
1033
|
-
constructor(port, host) {
|
|
1034
|
-
this.deferred = this.defer();
|
|
1035
|
-
// eslint-disable-next-line
|
|
1036
|
-
const net = require('net');
|
|
1037
|
-
console.log('Starting server');
|
|
1038
|
-
this.server = net.createServer((socket) => {
|
|
1039
|
-
console.log('Client connected');
|
|
1040
|
-
socket.on('data', (data) => {
|
|
1041
|
-
let text = data.toString();
|
|
1042
|
-
console.log('message received', JSON.stringify(text));
|
|
1043
|
-
//when we get the event to resolve, do it
|
|
1044
|
-
if (text === 'resolve') {
|
|
1045
|
-
console.log('Resolving promise');
|
|
1046
|
-
this.deferred.resolve();
|
|
1047
|
-
this.server.close();
|
|
1048
|
-
}
|
|
1049
|
-
});
|
|
1050
|
-
});
|
|
1051
|
-
this.server.listen(port, host);
|
|
1052
|
-
}
|
|
1053
|
-
afterProgramCreate(program) {
|
|
1054
|
-
// hijack the function to get workspace symbols, return a promise that resolves in the future
|
|
1055
|
-
program.getWorkspaceSymbols = () => {
|
|
1056
|
-
return this.deferred.promise;
|
|
1057
|
-
};
|
|
1058
|
-
}
|
|
1059
|
-
defer() {
|
|
1060
|
-
let resolve;
|
|
1061
|
-
let reject;
|
|
1062
|
-
let promise = new Promise((res, rej) => {
|
|
1063
|
-
resolve = res;
|
|
1064
|
-
reject = rej;
|
|
1065
|
-
});
|
|
1066
|
-
return {
|
|
1067
|
-
resolve: resolve,
|
|
1068
|
-
reject: reject,
|
|
1069
|
-
promise: promise
|
|
1070
|
-
};
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
|
-
const port = await getPort();
|
|
1074
|
-
const host = '127.0.0.1';
|
|
1075
|
-
//write a small brighterscript plugin to allow this test to communicate with the thread
|
|
1076
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/pluginsocket.js`, `
|
|
1077
|
-
${Plugin.toString()};
|
|
1078
|
-
exports.default = function() {
|
|
1079
|
-
return new Plugin(${port}, "${host}");
|
|
1080
|
-
};
|
|
1081
|
-
`);
|
|
1082
|
-
//write a bsconfig that will load this plugin
|
|
1083
|
-
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
1084
|
-
plugins: [
|
|
1085
|
-
`${testHelpers_spec_1.rootDir}/pluginsocket.js`
|
|
1086
|
-
]
|
|
1087
|
-
});
|
|
1088
|
-
//wait for the projects to finish syncing/loading
|
|
1089
|
-
await manager.syncProjects([Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings), { languageServer: Object.assign(Object.assign({}, testHelpers_spec_1.workspaceSettings.languageServer), { enableThreading: true }) })]);
|
|
1090
|
-
//establish the connection with the plugin
|
|
1091
|
-
const connection = net.createConnection({
|
|
1092
|
-
host: host,
|
|
1093
|
-
port: port
|
|
1094
|
-
});
|
|
1095
|
-
//do the request to fetch symbols (this will be stalled on purpose by our test plugin)
|
|
1096
|
-
let managerGetWorkspaceSymbolPromise = manager.getWorkspaceSymbol();
|
|
1097
|
-
//small sleep to let things settle
|
|
1098
|
-
await util_1.default.sleep(20);
|
|
1099
|
-
//now dispose the project (which should destroy all of the listeners)
|
|
1100
|
-
manager['removeProject'](manager.projects[0]);
|
|
1101
|
-
//settle again
|
|
1102
|
-
await util_1.default.sleep(20);
|
|
1103
|
-
console.log('Asking the client to resolve');
|
|
1104
|
-
//resolve the request
|
|
1105
|
-
connection.write('resolve');
|
|
1106
|
-
//now wait to see if we ever get the response back
|
|
1107
|
-
let result = await managerGetWorkspaceSymbolPromise;
|
|
1108
|
-
//the result should be an empty array, since the only project was rejected in the middle of the request
|
|
1109
|
-
(0, chai_1.expect)(result).to.eql([]);
|
|
1110
|
-
//test passes if the promise resolves
|
|
1111
|
-
});
|
|
1112
|
-
it('properly handles reloading when bsconfig.json contents change', async () => {
|
|
1113
|
-
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
1114
|
-
files: [
|
|
1115
|
-
'one'
|
|
1116
|
-
]
|
|
1117
|
-
});
|
|
1118
|
-
//wait for the projects to finish syncing/loading
|
|
1119
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
1120
|
-
const stub = sinon.stub(manager, 'reloadProject').callThrough();
|
|
1121
|
-
//change the file to new contents
|
|
1122
|
-
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
1123
|
-
files: [
|
|
1124
|
-
'two'
|
|
1125
|
-
]
|
|
1126
|
-
});
|
|
1127
|
-
await manager.handleFileChanges([{
|
|
1128
|
-
srcPath: `${testHelpers_spec_1.rootDir}/bsconfig.json`,
|
|
1129
|
-
type: vscode_languageserver_protocol_1.FileChangeType.Changed
|
|
1130
|
-
}]);
|
|
1131
|
-
//the project was reloaded
|
|
1132
|
-
(0, chai_1.expect)(stub.callCount).to.eql(1);
|
|
1133
|
-
//change the file to the same contents
|
|
1134
|
-
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
1135
|
-
files: [
|
|
1136
|
-
'two'
|
|
1137
|
-
]
|
|
1138
|
-
});
|
|
1139
|
-
await manager.handleFileChanges([{
|
|
1140
|
-
srcPath: `${testHelpers_spec_1.rootDir}/bsconfig.json`,
|
|
1141
|
-
type: vscode_languageserver_protocol_1.FileChangeType.Changed
|
|
1142
|
-
}]);
|
|
1143
|
-
//the project was not reloaded this time
|
|
1144
|
-
(0, chai_1.expect)(stub.callCount).to.eql(1);
|
|
1145
|
-
});
|
|
1146
|
-
it('properly handles reloading when manifest contents change', async () => {
|
|
1147
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/manifest`, 'title=MyApp\nbs_const=DEBUG=false');
|
|
1148
|
-
//wait for the projects to finish syncing/loading
|
|
1149
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
1150
|
-
const stub = sinon.stub(manager, 'reloadProject').callThrough();
|
|
1151
|
-
//change the manifest to new contents
|
|
1152
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/manifest`, 'title=MyApp\nbs_const=DEBUG=true');
|
|
1153
|
-
await manager.handleFileChanges([{
|
|
1154
|
-
srcPath: `${testHelpers_spec_1.rootDir}/manifest`,
|
|
1155
|
-
type: vscode_languageserver_protocol_1.FileChangeType.Changed
|
|
1156
|
-
}]);
|
|
1157
|
-
//the project was reloaded
|
|
1158
|
-
(0, chai_1.expect)(stub.callCount).to.eql(1);
|
|
1159
|
-
//change the manifest to the same contents
|
|
1160
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/manifest`, 'title=MyApp\nbs_const=DEBUG=true');
|
|
1161
|
-
await manager.handleFileChanges([{
|
|
1162
|
-
srcPath: `${testHelpers_spec_1.rootDir}/manifest`,
|
|
1163
|
-
type: vscode_languageserver_protocol_1.FileChangeType.Changed
|
|
1164
|
-
}]);
|
|
1165
|
-
//the project was not reloaded this time
|
|
1166
|
-
(0, chai_1.expect)(stub.callCount).to.eql(1);
|
|
1167
|
-
});
|
|
1168
|
-
it('reloads project when manifest is deleted', async () => {
|
|
1169
|
-
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/manifest`, 'title=MyApp');
|
|
1170
|
-
//wait for the projects to finish syncing/loading
|
|
1171
|
-
await manager.syncProjects([testHelpers_spec_1.workspaceSettings]);
|
|
1172
|
-
const stub = sinon.stub(manager, 'reloadProject').callThrough();
|
|
1173
|
-
//delete the manifest file
|
|
1174
|
-
fsExtra.removeSync(`${testHelpers_spec_1.rootDir}/manifest`);
|
|
1175
|
-
await manager.handleFileChanges([{
|
|
1176
|
-
srcPath: `${testHelpers_spec_1.rootDir}/manifest`,
|
|
1177
|
-
type: vscode_languageserver_protocol_1.FileChangeType.Deleted
|
|
1178
|
-
}]);
|
|
1179
|
-
//the project was reloaded because the manifest is gone
|
|
1180
|
-
(0, chai_1.expect)(stub.callCount).to.eql(1);
|
|
1181
|
-
});
|
|
1182
|
-
});
|
|
1183
|
-
//# sourceMappingURL=ProjectManager.spec.js.map
|