brighterscript 1.0.0-alpha.44 → 1.0.0-alpha.46
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/bsconfig.schema.json +6 -1
- package/dist/AstValidationSegmenter.js +6 -1
- package/dist/AstValidationSegmenter.js.map +1 -1
- package/dist/BsConfig.d.ts +4 -0
- package/dist/BusyStatusTracker.d.ts +37 -7
- package/dist/BusyStatusTracker.js +73 -8
- package/dist/BusyStatusTracker.js.map +1 -1
- package/dist/Cache.d.ts +0 -4
- package/dist/Cache.js +0 -6
- package/dist/Cache.js.map +1 -1
- package/dist/CodeActionUtil.d.ts +6 -1
- package/dist/CodeActionUtil.js +3 -0
- package/dist/CodeActionUtil.js.map +1 -1
- package/dist/CrossScopeValidator.d.ts +1 -1
- package/dist/CrossScopeValidator.js +8 -7
- package/dist/CrossScopeValidator.js.map +1 -1
- package/dist/DiagnosticCollection.d.ts +19 -5
- package/dist/DiagnosticCollection.js +71 -23
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +14 -1
- package/dist/DiagnosticFilterer.js +130 -12
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticManager.d.ts +11 -1
- package/dist/DiagnosticManager.js +192 -35
- package/dist/DiagnosticManager.js.map +1 -1
- package/dist/DiagnosticMessages.d.ts +19 -7
- package/dist/DiagnosticMessages.js +21 -9
- package/dist/DiagnosticMessages.js.map +1 -1
- package/dist/LanguageServer.d.ts +82 -139
- package/dist/LanguageServer.js +402 -980
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +9 -4
- package/dist/Logger.js +30 -6
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +8 -8
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +23 -4
- package/dist/Program.js +294 -194
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +22 -7
- package/dist/ProgramBuilder.js +44 -21
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +11 -6
- package/dist/Scope.js +60 -36
- package/dist/Scope.js.map +1 -1
- package/dist/SemanticTokenUtils.js +1 -1
- package/dist/SemanticTokenUtils.js.map +1 -1
- package/dist/astUtils/CachedLookups.js +0 -1
- package/dist/astUtils/CachedLookups.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +4 -4
- package/dist/astUtils/reflection.js +12 -10
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +3 -3
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.js +4 -2
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.d.ts +2 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js +147 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.js.map +1 -1
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js +44 -0
- package/dist/bscPlugin/codeActions/CodeActionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.js +15 -15
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +82 -5
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/hover/HoverProcessor.js +3 -0
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
- package/dist/bscPlugin/hover/HoverProcessor.spec.js +44 -0
- package/dist/bscPlugin/hover/HoverProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js +4 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.js.map +1 -1
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js +17 -0
- package/dist/bscPlugin/semanticTokens/BrsFileSemanticTokensProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.js +21 -0
- package/dist/bscPlugin/validation/BrsFileValidator.js.map +1 -1
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js +161 -7
- package/dist/bscPlugin/validation/BrsFileValidator.spec.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +4 -1
- package/dist/bscPlugin/validation/ScopeValidator.js +166 -63
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.spec.js +21 -9
- package/dist/bscPlugin/validation/ScopeValidator.spec.js.map +1 -1
- package/dist/common/Sequencer.d.ts +53 -0
- package/dist/common/Sequencer.js +233 -0
- package/dist/common/Sequencer.js.map +1 -0
- package/dist/common/Sequencer.spec.d.ts +1 -0
- package/dist/common/Sequencer.spec.js +75 -0
- package/dist/common/Sequencer.spec.js.map +1 -0
- package/dist/deferred.d.ts +2 -0
- package/dist/deferred.js +10 -0
- package/dist/deferred.js.map +1 -1
- package/dist/examples/plugins/removePrint.d.ts +2 -2
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/BrsFile.d.ts +1 -1
- package/dist/files/BrsFile.js +22 -42
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +155 -4
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/BscFile.d.ts +1 -0
- package/dist/files/LazyFileData.d.ts +1 -0
- package/dist/files/XmlFile.spec.js +1 -1
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/globalCallables.js +189 -189
- package/dist/globalCallables.js.map +1 -1
- package/dist/interfaces.d.ts +56 -13
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Lexer.js +1 -1
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/logging.d.ts +6 -1
- package/dist/logging.js +14 -1
- package/dist/logging.js.map +1 -1
- package/dist/lsp/ActionQueue.d.ts +35 -0
- package/dist/lsp/ActionQueue.js +115 -0
- package/dist/lsp/ActionQueue.js.map +1 -0
- package/dist/lsp/ActionQueue.spec.d.ts +1 -0
- package/dist/lsp/ActionQueue.spec.js +80 -0
- package/dist/lsp/ActionQueue.spec.js.map +1 -0
- package/dist/lsp/DocumentManager.d.ts +63 -0
- package/dist/lsp/DocumentManager.js +122 -0
- package/dist/lsp/DocumentManager.js.map +1 -0
- package/dist/lsp/DocumentManager.spec.d.ts +1 -0
- package/dist/lsp/DocumentManager.spec.js +103 -0
- package/dist/lsp/DocumentManager.spec.js.map +1 -0
- package/dist/lsp/LspProject.d.ts +231 -0
- package/dist/lsp/LspProject.js +3 -0
- package/dist/lsp/LspProject.js.map +1 -0
- package/dist/lsp/PathFilterer.d.ts +75 -0
- package/dist/lsp/PathFilterer.js +196 -0
- package/dist/lsp/PathFilterer.js.map +1 -0
- package/dist/lsp/PathFilterer.spec.d.ts +1 -0
- package/dist/lsp/PathFilterer.spec.js +182 -0
- package/dist/lsp/PathFilterer.spec.js.map +1 -0
- package/dist/lsp/Project.d.ts +167 -0
- package/dist/lsp/Project.js +432 -0
- package/dist/lsp/Project.js.map +1 -0
- package/dist/lsp/Project.spec.d.ts +1 -0
- package/dist/lsp/Project.spec.js +220 -0
- package/dist/lsp/Project.spec.js.map +1 -0
- package/dist/lsp/ProjectManager.d.ts +221 -0
- package/dist/lsp/ProjectManager.js +754 -0
- package/dist/lsp/ProjectManager.js.map +1 -0
- package/dist/lsp/ProjectManager.spec.d.ts +1 -0
- package/dist/lsp/ProjectManager.spec.js +783 -0
- package/dist/lsp/ProjectManager.spec.js.map +1 -0
- package/dist/lsp/ReaderWriterManager.d.ts +21 -0
- package/dist/lsp/ReaderWriterManager.js +60 -0
- package/dist/lsp/ReaderWriterManager.js.map +1 -0
- package/dist/lsp/worker/MessageHandler.d.ts +99 -0
- package/dist/lsp/worker/MessageHandler.js +138 -0
- package/dist/lsp/worker/MessageHandler.js.map +1 -0
- package/dist/lsp/worker/MessageHandler.spec.d.ts +1 -0
- package/dist/lsp/worker/MessageHandler.spec.js +64 -0
- package/dist/lsp/worker/MessageHandler.spec.js.map +1 -0
- package/dist/lsp/worker/WorkerPool.d.ts +38 -0
- package/dist/lsp/worker/WorkerPool.js +78 -0
- package/dist/lsp/worker/WorkerPool.js.map +1 -0
- package/dist/lsp/worker/WorkerPool.spec.d.ts +1 -0
- package/dist/lsp/worker/WorkerPool.spec.js +59 -0
- package/dist/lsp/worker/WorkerPool.spec.js.map +1 -0
- package/dist/lsp/worker/WorkerThreadProject.d.ts +144 -0
- package/dist/lsp/worker/WorkerThreadProject.js +183 -0
- package/dist/lsp/worker/WorkerThreadProject.js.map +1 -0
- package/dist/lsp/worker/WorkerThreadProject.spec.d.ts +2 -0
- package/dist/lsp/worker/WorkerThreadProject.spec.js +68 -0
- package/dist/lsp/worker/WorkerThreadProject.spec.js.map +1 -0
- package/dist/lsp/worker/WorkerThreadProjectRunner.d.ts +15 -0
- package/dist/lsp/worker/WorkerThreadProjectRunner.js +58 -0
- package/dist/lsp/worker/WorkerThreadProjectRunner.js.map +1 -0
- package/dist/parser/Expression.d.ts +1 -0
- package/dist/parser/Expression.js +65 -3
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.spec.js +12 -0
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/Statement.js +2 -2
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js +47 -0
- package/dist/parser/tests/expression/NullCoalescenceExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +51 -5
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/parser/tests/expression/TernaryExpression.spec.js +44 -0
- package/dist/parser/tests/expression/TernaryExpression.spec.js.map +1 -1
- package/dist/roku-types/data.json +880 -756
- package/dist/roku-types/index.d.ts +17 -0
- package/dist/types/BooleanType.d.ts +0 -2
- package/dist/types/BooleanType.js +4 -6
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BscType.js +5 -0
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BuiltInInterfaceAdder.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.js +24 -17
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -1
- package/dist/types/DoubleType.d.ts +0 -2
- package/dist/types/DoubleType.js +4 -6
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DynamicType.d.ts +0 -2
- package/dist/types/DynamicType.js +3 -5
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/FloatType.d.ts +0 -2
- package/dist/types/FloatType.js +4 -6
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FunctionType.d.ts +0 -2
- package/dist/types/FunctionType.js +5 -7
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/IntegerType.d.ts +0 -2
- package/dist/types/IntegerType.js +4 -6
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +0 -2
- package/dist/types/LongIntegerType.js +4 -6
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/ObjectType.d.ts +3 -3
- package/dist/types/ObjectType.js +6 -8
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/StringType.d.ts +0 -2
- package/dist/types/StringType.js +4 -6
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/VoidType.d.ts +0 -2
- package/dist/types/VoidType.js +4 -6
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/helpers.d.ts +4 -0
- package/dist/types/helpers.js +5 -1
- package/dist/types/helpers.js.map +1 -1
- package/dist/util.d.ts +48 -16
- package/dist/util.js +203 -70
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.js +2 -2
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +15 -5
- package/CHANGELOG.md +0 -2352
|
@@ -0,0 +1,783 @@
|
|
|
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([{
|
|
86
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
87
|
+
}]);
|
|
88
|
+
const project = manager.projects[0];
|
|
89
|
+
//force validation to take a while
|
|
90
|
+
sinon.stub(project['builder'].program, 'validate').callsFake(async () => {
|
|
91
|
+
await util_1.default.sleep(100);
|
|
92
|
+
});
|
|
93
|
+
(0, chai_1.expect)(manager.busyStatusTracker.status).to.eql('idle');
|
|
94
|
+
//run several validations (which cancel the previous)
|
|
95
|
+
void project.validate();
|
|
96
|
+
await util_1.default.sleep(10);
|
|
97
|
+
void project.validate();
|
|
98
|
+
await util_1.default.sleep(10);
|
|
99
|
+
void project.validate();
|
|
100
|
+
await util_1.default.sleep(10);
|
|
101
|
+
//busy status should be active
|
|
102
|
+
(0, chai_1.expect)(manager.busyStatusTracker.status).to.eql('busy');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
describe('getHover', () => {
|
|
106
|
+
it('dedupes identical hover contents', async () => {
|
|
107
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, `
|
|
108
|
+
sub main()
|
|
109
|
+
end sub
|
|
110
|
+
`);
|
|
111
|
+
await manager.syncProjects([{
|
|
112
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
113
|
+
}]);
|
|
114
|
+
sinon.stub(manager.projects[0], 'getHover').returns(Promise.resolve([{
|
|
115
|
+
contents: ['one', 'two', 'three'],
|
|
116
|
+
range: util_1.default.createRange(1, 1, 1, 1)
|
|
117
|
+
}, {
|
|
118
|
+
contents: ['two', 'three', 'four'],
|
|
119
|
+
range: util_1.default.createRange(2, 2, 2, 2)
|
|
120
|
+
}]));
|
|
121
|
+
const hover = await manager.getHover({
|
|
122
|
+
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`,
|
|
123
|
+
position: util_1.default.createPosition(1, 23)
|
|
124
|
+
});
|
|
125
|
+
(0, chai_1.expect)(hover).to.eql({
|
|
126
|
+
contents: ['one', 'two', 'three', 'four'],
|
|
127
|
+
range: util_1.default.createRange(1, 1, 2, 2)
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe('syncProjects', () => {
|
|
132
|
+
it('does not crash on zero projects', async () => {
|
|
133
|
+
await manager.syncProjects([]);
|
|
134
|
+
});
|
|
135
|
+
it('finds bsconfig in a folder', async () => {
|
|
136
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, '');
|
|
137
|
+
await manager.syncProjects([{
|
|
138
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
139
|
+
}]);
|
|
140
|
+
(0, chai_1.expect)(manager.projects[0].projectPath).to.eql((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`);
|
|
141
|
+
});
|
|
142
|
+
it('finds bsconfig at root and also in subfolder', async () => {
|
|
143
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, '');
|
|
144
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/bsconfig.json`, '');
|
|
145
|
+
await manager.syncProjects([{
|
|
146
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
147
|
+
}]);
|
|
148
|
+
(0, chai_1.expect)(manager.projects.map(x => x.projectPath).sort()).to.eql([
|
|
149
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`,
|
|
150
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir`
|
|
151
|
+
]);
|
|
152
|
+
});
|
|
153
|
+
it('skips excluded bsconfig bsconfig in a folder', async () => {
|
|
154
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, '');
|
|
155
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/bsconfig.json`, '');
|
|
156
|
+
await manager.syncProjects([{
|
|
157
|
+
workspaceFolder: testHelpers_spec_1.rootDir,
|
|
158
|
+
excludePatterns: ['subdir/**/*']
|
|
159
|
+
}]);
|
|
160
|
+
(0, chai_1.expect)(manager.projects.map(x => x.projectPath)).to.eql([
|
|
161
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`
|
|
162
|
+
]);
|
|
163
|
+
});
|
|
164
|
+
it('uses rootDir when manifest found but no brightscript file', async () => {
|
|
165
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/manifest`, '');
|
|
166
|
+
await manager.syncProjects([{
|
|
167
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
168
|
+
}]);
|
|
169
|
+
(0, chai_1.expect)(manager.projects.map(x => x.projectPath)).to.eql([
|
|
170
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}`
|
|
171
|
+
]);
|
|
172
|
+
});
|
|
173
|
+
it('gets diagnostics from plugins added in afterProgramValidate', async () => {
|
|
174
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/plugin.js`, `
|
|
175
|
+
module.exports = function () {
|
|
176
|
+
return {
|
|
177
|
+
afterProgramValidate: function(event) {
|
|
178
|
+
var file = event.program.getFile('source/main.brs');
|
|
179
|
+
//add a diagnostic from a plugin
|
|
180
|
+
event.program.diagnostics.register({
|
|
181
|
+
message: 'Test diagnostic',
|
|
182
|
+
code: 'test-123',
|
|
183
|
+
location: {},
|
|
184
|
+
severity: 1
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
`);
|
|
190
|
+
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
191
|
+
plugins: [
|
|
192
|
+
'./plugin.js'
|
|
193
|
+
]
|
|
194
|
+
});
|
|
195
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, `
|
|
196
|
+
sub test()
|
|
197
|
+
print nameNotDefined
|
|
198
|
+
end sub
|
|
199
|
+
`);
|
|
200
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/manifest`, '');
|
|
201
|
+
await manager.syncProjects([{
|
|
202
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
203
|
+
}]);
|
|
204
|
+
(0, testHelpers_spec_1.expectDiagnostics)(await onNextDiagnostics(), [
|
|
205
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('nameNotDefined').message,
|
|
206
|
+
'Test diagnostic'
|
|
207
|
+
]);
|
|
208
|
+
});
|
|
209
|
+
it('uses subdir when manifest and brightscript file found', async () => {
|
|
210
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/manifest`, '');
|
|
211
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir/source/main.brs`, '');
|
|
212
|
+
await manager.syncProjects([{
|
|
213
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
214
|
+
}]);
|
|
215
|
+
(0, chai_1.expect)(manager.projects.map(x => x.projectPath)).to.eql([
|
|
216
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir`
|
|
217
|
+
]);
|
|
218
|
+
});
|
|
219
|
+
it('removes stale projects', async () => {
|
|
220
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`, '');
|
|
221
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`, '');
|
|
222
|
+
await manager.syncProjects([{
|
|
223
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
224
|
+
}]);
|
|
225
|
+
(0, chai_1.expect)(manager.projects.map(x => x.projectPath).sort()).to.eql([
|
|
226
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir1`,
|
|
227
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir2`
|
|
228
|
+
]);
|
|
229
|
+
fsExtra.removeSync(`${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`);
|
|
230
|
+
await manager.syncProjects([{
|
|
231
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
232
|
+
}]);
|
|
233
|
+
(0, chai_1.expect)(manager.projects.map(x => x.projectPath).sort()).to.eql([
|
|
234
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir2`
|
|
235
|
+
]);
|
|
236
|
+
});
|
|
237
|
+
it('keeps existing projects on subsequent sync calls', async () => {
|
|
238
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir1/bsconfig.json`, '');
|
|
239
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/subdir2/bsconfig.json`, '');
|
|
240
|
+
await manager.syncProjects([{
|
|
241
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
242
|
+
}]);
|
|
243
|
+
(0, chai_1.expect)(manager.projects.map(x => x.projectPath).sort()).to.eql([
|
|
244
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir1`,
|
|
245
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir2`
|
|
246
|
+
]);
|
|
247
|
+
await manager.syncProjects([{
|
|
248
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
249
|
+
}]);
|
|
250
|
+
(0, chai_1.expect)(manager.projects.map(x => x.projectPath).sort()).to.eql([
|
|
251
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir1`,
|
|
252
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/subdir2`
|
|
253
|
+
]);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
describe('getCompletions', () => {
|
|
257
|
+
it('works for quick file changes', async () => {
|
|
258
|
+
//set up the project
|
|
259
|
+
await manager.syncProjects([{
|
|
260
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
261
|
+
}]);
|
|
262
|
+
//add the namespace first
|
|
263
|
+
await setFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/alpha.bs`, `
|
|
264
|
+
namespace alpha
|
|
265
|
+
enum Direction
|
|
266
|
+
up
|
|
267
|
+
end enum
|
|
268
|
+
end namespace
|
|
269
|
+
`);
|
|
270
|
+
//add the baseline file
|
|
271
|
+
await setFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`, `
|
|
272
|
+
sub test()
|
|
273
|
+
thing = alpha.Directio
|
|
274
|
+
end sub
|
|
275
|
+
`);
|
|
276
|
+
await manager.onIdle();
|
|
277
|
+
//now for the test. type a char, request completions, type a char, request completions (just like how vscode does it)
|
|
278
|
+
void setFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`, `
|
|
279
|
+
sub test()
|
|
280
|
+
thing = alpha.Direction
|
|
281
|
+
end sub
|
|
282
|
+
`);
|
|
283
|
+
// const completionsPromise1 = manager.getCompletions({
|
|
284
|
+
// srcPath: s`${rootDir}/source/main.bs`,
|
|
285
|
+
// position: util.createPosition(2, 43)
|
|
286
|
+
// });
|
|
287
|
+
//request completions
|
|
288
|
+
void setFile((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`, `
|
|
289
|
+
sub test()
|
|
290
|
+
thing = alpha.Direction.
|
|
291
|
+
end sub
|
|
292
|
+
`);
|
|
293
|
+
const completionsPromise2 = manager.getCompletions({
|
|
294
|
+
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`,
|
|
295
|
+
position: util_1.default.createPosition(2, 44)
|
|
296
|
+
});
|
|
297
|
+
// //the first set of completions should only have the `alpha.Direction` enum
|
|
298
|
+
// expectCompletionsIncludes(await completionsPromise1, [{
|
|
299
|
+
// label: 'Direction'
|
|
300
|
+
// }]);
|
|
301
|
+
//the next set of completions should only have the alpha.Direction.up enum member
|
|
302
|
+
(0, testHelpers_spec_1.expectCompletionsIncludes)(await completionsPromise2, [{
|
|
303
|
+
label: 'up'
|
|
304
|
+
}]);
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
describe('flushDocumentChanges', () => {
|
|
308
|
+
it('does not crash when getting undefined back from projects', async () => {
|
|
309
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, ``);
|
|
310
|
+
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, {
|
|
311
|
+
rootDir: testHelpers_spec_1.rootDir
|
|
312
|
+
});
|
|
313
|
+
await manager.syncProjects([{
|
|
314
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
315
|
+
}]);
|
|
316
|
+
sinon.stub(manager.projects[0], 'applyFileChanges').returns(Promise.resolve([
|
|
317
|
+
//return an undefined item, which used to cause a specific crash
|
|
318
|
+
undefined
|
|
319
|
+
]));
|
|
320
|
+
await manager['flushDocumentChanges']({
|
|
321
|
+
actions: [{
|
|
322
|
+
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`,
|
|
323
|
+
type: 'set',
|
|
324
|
+
fileContents: 'sub main():end sub',
|
|
325
|
+
allowStandaloneProject: true
|
|
326
|
+
}]
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
describe('handleFileChanges', () => {
|
|
331
|
+
it('only sends files to the project that match the include patterns for that project', async () => {
|
|
332
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib1/a.brs`, ``);
|
|
333
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib2/a.brs`, ``);
|
|
334
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib1/b.brs`, ``);
|
|
335
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib2/b.brs`, ``);
|
|
336
|
+
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/project1/bsconfig.json`, {
|
|
337
|
+
rootDir: testHelpers_spec_1.rootDir,
|
|
338
|
+
files: [
|
|
339
|
+
'source/**/a.brs'
|
|
340
|
+
]
|
|
341
|
+
});
|
|
342
|
+
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/project2/bsconfig.json`, {
|
|
343
|
+
rootDir: testHelpers_spec_1.rootDir,
|
|
344
|
+
files: [
|
|
345
|
+
'source/**/b.brs'
|
|
346
|
+
]
|
|
347
|
+
});
|
|
348
|
+
await manager.syncProjects([{
|
|
349
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
350
|
+
}]);
|
|
351
|
+
let deferred1 = new deferred_1.Deferred();
|
|
352
|
+
let deferred2 = new deferred_1.Deferred();
|
|
353
|
+
const project1 = manager.projects.find(x => x.bsconfigPath.includes('project1'));
|
|
354
|
+
const project2 = manager.projects.find(x => x.bsconfigPath.includes('project2'));
|
|
355
|
+
const project1Stub = sinon.stub(project1, 'applyFileChanges').callsFake(async (...args) => {
|
|
356
|
+
const result = await project1Stub.wrappedMethod.apply(project1, args);
|
|
357
|
+
deferred1.resolve();
|
|
358
|
+
return result;
|
|
359
|
+
});
|
|
360
|
+
const project2Stub = sinon.stub(project2, 'applyFileChanges').callsFake(async (...args) => {
|
|
361
|
+
const result = await project2Stub.wrappedMethod.apply(project1, args);
|
|
362
|
+
deferred2.resolve();
|
|
363
|
+
return result;
|
|
364
|
+
});
|
|
365
|
+
await manager.handleFileChanges([
|
|
366
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib1/a.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
|
|
367
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib2/a.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
|
|
368
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib1/b.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
|
|
369
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib2/b.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed }
|
|
370
|
+
]);
|
|
371
|
+
//wait for the functions to finish being called
|
|
372
|
+
await Promise.all([
|
|
373
|
+
deferred1.promise,
|
|
374
|
+
deferred2.promise
|
|
375
|
+
]);
|
|
376
|
+
//project1 should only receive a.brs files
|
|
377
|
+
(0, chai_1.expect)(project1Stub.getCall(0).args[0].map(x => x.srcPath)).to.eql([
|
|
378
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib1/a.brs`,
|
|
379
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2/a.brs`
|
|
380
|
+
]);
|
|
381
|
+
//project2 should only receive b.brs files
|
|
382
|
+
(0, chai_1.expect)(project2Stub.getCall(0).args[0].map(x => x.srcPath)).to.eql([
|
|
383
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib1/b.brs`,
|
|
384
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/lib2/b.brs`
|
|
385
|
+
]);
|
|
386
|
+
});
|
|
387
|
+
it('excludes files based on global exclude patterns', async () => {
|
|
388
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/file1.md`, ``);
|
|
389
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/file2.brs`, ``);
|
|
390
|
+
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
391
|
+
files: [
|
|
392
|
+
'source/**/*.brs'
|
|
393
|
+
]
|
|
394
|
+
});
|
|
395
|
+
await manager.syncProjects([{
|
|
396
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
397
|
+
}]);
|
|
398
|
+
const stub = sinon.stub(manager, 'handleFileChange').callThrough();
|
|
399
|
+
//register an exclusion filter
|
|
400
|
+
pathFilterer.registerExcludeList(testHelpers_spec_1.rootDir, [
|
|
401
|
+
'**/*.md'
|
|
402
|
+
]);
|
|
403
|
+
//make sure the .md file is ignored
|
|
404
|
+
await manager.handleFileChanges([
|
|
405
|
+
{ srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file1.md`, type: vscode_languageserver_protocol_1.FileChangeType.Created },
|
|
406
|
+
{ srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Created }
|
|
407
|
+
]);
|
|
408
|
+
await manager.onIdle();
|
|
409
|
+
(0, chai_1.expect)(stub.getCalls().map(x => x.args[0]).map(x => x.srcPath)).to.eql([
|
|
410
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`
|
|
411
|
+
]);
|
|
412
|
+
stub.reset();
|
|
413
|
+
//remove all filters, make sure the markdown file is included
|
|
414
|
+
pathFilterer.clear();
|
|
415
|
+
await manager.handleFileChanges([
|
|
416
|
+
{ srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file1.md`, type: vscode_languageserver_protocol_1.FileChangeType.Created },
|
|
417
|
+
{ srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Created }
|
|
418
|
+
]);
|
|
419
|
+
await manager.onIdle();
|
|
420
|
+
(0, chai_1.expect)(stub.getCalls().flatMap(x => x.args[0]).map(x => x.srcPath)).to.eql([
|
|
421
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file1.md`,
|
|
422
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`
|
|
423
|
+
]);
|
|
424
|
+
});
|
|
425
|
+
it('keeps files from bsconfig.json even if the path matches an exclude list', async () => {
|
|
426
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/file1.md`, ``);
|
|
427
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/file2.brs`, ``);
|
|
428
|
+
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
429
|
+
files: ['source/**/*']
|
|
430
|
+
});
|
|
431
|
+
await manager.syncProjects([{
|
|
432
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
433
|
+
}]);
|
|
434
|
+
const stub = sinon.stub(manager['projects'][0], 'applyFileChanges').callThrough();
|
|
435
|
+
//register an exclusion filter
|
|
436
|
+
pathFilterer.registerExcludeList(testHelpers_spec_1.rootDir, [
|
|
437
|
+
'**/*.md'
|
|
438
|
+
]);
|
|
439
|
+
//make sure the .md file is included because of its project's files array
|
|
440
|
+
await manager.handleFileChanges([
|
|
441
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/file1.md`, type: vscode_languageserver_protocol_1.FileChangeType.Created },
|
|
442
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/file2.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Created }
|
|
443
|
+
]);
|
|
444
|
+
await manager.onIdle();
|
|
445
|
+
(0, chai_1.expect)(stub.getCalls().flatMap(x => x.args[0]).map(x => x.srcPath)).to.eql([
|
|
446
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file1.md`,
|
|
447
|
+
(0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/file2.brs`
|
|
448
|
+
]);
|
|
449
|
+
});
|
|
450
|
+
it('does not create a standalone project for files that exist in a known project', async () => {
|
|
451
|
+
fsExtra.outputFileSync((0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`, `sub main() : end sub`);
|
|
452
|
+
await manager.syncProjects([{
|
|
453
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
454
|
+
}]);
|
|
455
|
+
await onNextDiagnostics();
|
|
456
|
+
await manager.handleFileChanges([
|
|
457
|
+
{ srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed, fileContents: `'test`, allowStandaloneProject: true }
|
|
458
|
+
]);
|
|
459
|
+
await onNextDiagnostics();
|
|
460
|
+
//there should NOT be a standalone project
|
|
461
|
+
(0, chai_1.expect)(manager['standaloneProjects'].size).to.eql(0);
|
|
462
|
+
});
|
|
463
|
+
it('converts a missing file to a delete', async () => {
|
|
464
|
+
await manager.syncProjects([{
|
|
465
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
466
|
+
}]);
|
|
467
|
+
await onNextDiagnostics();
|
|
468
|
+
let applyFileChangesDeferred = new deferred_1.Deferred();
|
|
469
|
+
const project1 = manager.projects[0];
|
|
470
|
+
const project1Stub = sinon.stub(project1, 'applyFileChanges').callsFake(async (...args) => {
|
|
471
|
+
const result = await project1Stub.wrappedMethod.apply(project1, args);
|
|
472
|
+
applyFileChangesDeferred.resolve(result);
|
|
473
|
+
return result;
|
|
474
|
+
});
|
|
475
|
+
//emit created and changed events for files that don't exist. These turn into delete events
|
|
476
|
+
await manager.handleFileChanges([
|
|
477
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/missing1.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Created },
|
|
478
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/missing2.brs`, type: vscode_languageserver_protocol_1.FileChangeType.Changed }
|
|
479
|
+
]);
|
|
480
|
+
//wait for the next set of diagnostics to arrive (signifying the files have been applied)
|
|
481
|
+
const result = await applyFileChangesDeferred.promise;
|
|
482
|
+
//make sure the project has these files
|
|
483
|
+
(0, chai_1.expect)(result.map(x => {
|
|
484
|
+
return { type: x.type, srcPath: x.srcPath };
|
|
485
|
+
})).to.eql([{
|
|
486
|
+
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/missing1.brs`,
|
|
487
|
+
type: 'set'
|
|
488
|
+
}, {
|
|
489
|
+
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/missing2.brs`,
|
|
490
|
+
type: 'set'
|
|
491
|
+
}, {
|
|
492
|
+
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/missing1.brs`,
|
|
493
|
+
type: 'delete'
|
|
494
|
+
}, {
|
|
495
|
+
srcPath: (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/missing2.brs`,
|
|
496
|
+
type: 'delete'
|
|
497
|
+
}]);
|
|
498
|
+
});
|
|
499
|
+
it('properly syncs changes', async () => {
|
|
500
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib1.brs`, `sub test1():print "alpha":end sub`);
|
|
501
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/lib2.brs`, `sub test2():print "beta":end sub`);
|
|
502
|
+
await manager.syncProjects([{
|
|
503
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
504
|
+
}]);
|
|
505
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(await onNextDiagnostics());
|
|
506
|
+
await manager.handleFileChanges([
|
|
507
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib1.brs`, fileContents: `sub test1():print alpha:end sub`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
|
|
508
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib2.brs`, fileContents: `sub test2()::print beta:end sub`, type: vscode_languageserver_protocol_1.FileChangeType.Changed }
|
|
509
|
+
]);
|
|
510
|
+
(0, testHelpers_spec_1.expectDiagnostics)(await onNextDiagnostics(), [
|
|
511
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('alpha').message,
|
|
512
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('beta').message
|
|
513
|
+
]);
|
|
514
|
+
await manager.handleFileChanges([
|
|
515
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib1.brs`, fileContents: `sub test1():print "alpha":end sub`, type: vscode_languageserver_protocol_1.FileChangeType.Changed },
|
|
516
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/lib2.brs`, fileContents: `sub test2()::print "beta":end sub`, type: vscode_languageserver_protocol_1.FileChangeType.Changed }
|
|
517
|
+
]);
|
|
518
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(await onNextDiagnostics());
|
|
519
|
+
});
|
|
520
|
+
it('adds all new files in a folder', async () => {
|
|
521
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, `sub main():print "main":end sub`);
|
|
522
|
+
await manager.syncProjects([{
|
|
523
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
524
|
+
}]);
|
|
525
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(await onNextDiagnostics());
|
|
526
|
+
//add a few files to a folder, then register that folder as an "add"
|
|
527
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/alpha/beta.brs`, `sub beta(): print one: end sub`);
|
|
528
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/alpha/charlie/delta.brs`, `sub delta():print two:end sub`);
|
|
529
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/echo/foxtrot.brs`, `sub foxtrot():print three:end sub`);
|
|
530
|
+
await manager.handleFileChanges([
|
|
531
|
+
//register the entire folder as an "add"
|
|
532
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/libs`, type: vscode_languageserver_protocol_1.FileChangeType.Created }
|
|
533
|
+
]);
|
|
534
|
+
(0, testHelpers_spec_1.expectDiagnostics)(await onNextDiagnostics(), [
|
|
535
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('one').message,
|
|
536
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('two').message,
|
|
537
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('three').message
|
|
538
|
+
]);
|
|
539
|
+
});
|
|
540
|
+
it('removes all files in a folder', async () => {
|
|
541
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/main.brs`, `sub main():print "main":end sub`);
|
|
542
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/alpha/beta.brs`, `sub beta(): print one: end sub`);
|
|
543
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/alpha/charlie/delta.brs`, `sub delta():print two:end sub`);
|
|
544
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/source/libs/echo/foxtrot.brs`, `sub foxtrot():print three:end sub`);
|
|
545
|
+
await manager.syncProjects([{
|
|
546
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
547
|
+
}]);
|
|
548
|
+
(0, testHelpers_spec_1.expectDiagnostics)(await onNextDiagnostics(), [
|
|
549
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('one').message,
|
|
550
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('two').message,
|
|
551
|
+
DiagnosticMessages_1.DiagnosticMessages.cannotFindName('three').message
|
|
552
|
+
]);
|
|
553
|
+
await manager.handleFileChanges([
|
|
554
|
+
//register the entire folder as an "add"
|
|
555
|
+
{ srcPath: `${testHelpers_spec_1.rootDir}/source/libs`, type: vscode_languageserver_protocol_1.FileChangeType.Deleted }
|
|
556
|
+
]);
|
|
557
|
+
(0, testHelpers_spec_1.expectZeroDiagnostics)(await onNextDiagnostics());
|
|
558
|
+
});
|
|
559
|
+
});
|
|
560
|
+
describe('threading', () => {
|
|
561
|
+
before(async function workerThreadWarmup() {
|
|
562
|
+
this.timeout(20000);
|
|
563
|
+
await (0, WorkerThreadProject_spec_1.getWakeWorkerThreadPromise)();
|
|
564
|
+
});
|
|
565
|
+
it('spawns a worker thread when threading is enabled', async () => {
|
|
566
|
+
await manager.syncProjects([{
|
|
567
|
+
workspaceFolder: testHelpers_spec_1.rootDir,
|
|
568
|
+
enableThreading: true
|
|
569
|
+
}]);
|
|
570
|
+
(0, chai_1.expect)(manager.projects[0]).instanceof(WorkerThreadProject_1.WorkerThreadProject);
|
|
571
|
+
});
|
|
572
|
+
});
|
|
573
|
+
describe('getProject', () => {
|
|
574
|
+
it('uses .projectPath if param is not a string', async () => {
|
|
575
|
+
await manager.syncProjects([{
|
|
576
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
577
|
+
}]);
|
|
578
|
+
(0, chai_1.expect)(manager['getProject']({
|
|
579
|
+
projectPath: testHelpers_spec_1.rootDir
|
|
580
|
+
})).to.include({
|
|
581
|
+
projectPath: testHelpers_spec_1.rootDir
|
|
582
|
+
});
|
|
583
|
+
});
|
|
584
|
+
});
|
|
585
|
+
describe('createAndActivateProject', () => {
|
|
586
|
+
it('skips creating project if we already have it', async () => {
|
|
587
|
+
await manager.syncProjects([{
|
|
588
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
589
|
+
}]);
|
|
590
|
+
await manager['createAndActivateProject']({
|
|
591
|
+
projectPath: testHelpers_spec_1.rootDir
|
|
592
|
+
});
|
|
593
|
+
(0, chai_1.expect)(manager.projects).to.be.length(1);
|
|
594
|
+
});
|
|
595
|
+
it('uses given projectNumber', async () => {
|
|
596
|
+
await manager['createAndActivateProject']({
|
|
597
|
+
projectPath: testHelpers_spec_1.rootDir,
|
|
598
|
+
workspaceFolder: testHelpers_spec_1.rootDir,
|
|
599
|
+
projectNumber: 3
|
|
600
|
+
});
|
|
601
|
+
(0, chai_1.expect)(manager.projects[0].projectNumber).to.eql(3);
|
|
602
|
+
});
|
|
603
|
+
it('properly tracks a failed run', async () => {
|
|
604
|
+
//force a total crash
|
|
605
|
+
sinon.stub(Project_1.Project.prototype, 'activate').returns(Promise.reject(new Error('Critical failure')));
|
|
606
|
+
let error;
|
|
607
|
+
try {
|
|
608
|
+
await manager['createAndActivateProject']({
|
|
609
|
+
projectPath: testHelpers_spec_1.rootDir,
|
|
610
|
+
workspaceFolder: testHelpers_spec_1.rootDir,
|
|
611
|
+
bsconfigPath: 'subdir1/brsconfig.json'
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
catch (e) {
|
|
615
|
+
error = e;
|
|
616
|
+
}
|
|
617
|
+
(0, chai_1.expect)(error).to.include({ message: 'Critical failure' });
|
|
618
|
+
});
|
|
619
|
+
});
|
|
620
|
+
describe('removeProject', () => {
|
|
621
|
+
it('handles undefined', async () => {
|
|
622
|
+
manager['removeProject'](undefined);
|
|
623
|
+
await manager.syncProjects([{
|
|
624
|
+
workspaceFolder: testHelpers_spec_1.rootDir
|
|
625
|
+
}]);
|
|
626
|
+
manager['removeProject'](undefined);
|
|
627
|
+
});
|
|
628
|
+
it('does not crash when removing project that is not there', () => {
|
|
629
|
+
manager['removeProject']({
|
|
630
|
+
projectPath: testHelpers_spec_1.rootDir,
|
|
631
|
+
dispose: () => { }
|
|
632
|
+
});
|
|
633
|
+
});
|
|
634
|
+
});
|
|
635
|
+
describe('getSemanticTokens', () => {
|
|
636
|
+
it('waits until the project is ready', () => {
|
|
637
|
+
});
|
|
638
|
+
});
|
|
639
|
+
describe('standalone projects', () => {
|
|
640
|
+
it('creates a standalone project for files not found in a project', async () => {
|
|
641
|
+
var _a;
|
|
642
|
+
await manager.syncProjects([]);
|
|
643
|
+
await manager.handleFileChanges([{
|
|
644
|
+
srcPath: `${testHelpers_spec_1.rootDir}/source/main.brs`,
|
|
645
|
+
type: vscode_languageserver_protocol_1.FileChangeType.Created,
|
|
646
|
+
fileContents: `sub main():print "main":end sub`,
|
|
647
|
+
allowStandaloneProject: true
|
|
648
|
+
}]);
|
|
649
|
+
await onNextDiagnostics();
|
|
650
|
+
(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`);
|
|
651
|
+
//it deletes the standalone project when the file is closed
|
|
652
|
+
await manager.handleFileClose({
|
|
653
|
+
srcPath: `${testHelpers_spec_1.rootDir}/source/main.brs`
|
|
654
|
+
});
|
|
655
|
+
(0, chai_1.expect)(manager['standaloneProjects'].size).to.eql(0);
|
|
656
|
+
});
|
|
657
|
+
});
|
|
658
|
+
it('completes promise when project is disposed in the middle of a flow', async function () {
|
|
659
|
+
this.timeout(20000);
|
|
660
|
+
//small plugin to communicate over a socket inside the worker thread.
|
|
661
|
+
//This transpiles from tsc use `require()` for all imports and don't reference external vars
|
|
662
|
+
class Plugin {
|
|
663
|
+
constructor(port, host) {
|
|
664
|
+
this.deferred = this.defer();
|
|
665
|
+
// eslint-disable-next-line
|
|
666
|
+
const net = require('net');
|
|
667
|
+
console.log('Starting server');
|
|
668
|
+
this.server = net.createServer((socket) => {
|
|
669
|
+
console.log('Client connected');
|
|
670
|
+
socket.on('data', (data) => {
|
|
671
|
+
let text = data.toString();
|
|
672
|
+
console.log('message received', JSON.stringify(text));
|
|
673
|
+
//when we get the event to resolve, do it
|
|
674
|
+
if (text === 'resolve') {
|
|
675
|
+
console.log('Resolving promise');
|
|
676
|
+
this.deferred.resolve();
|
|
677
|
+
this.server.close();
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
});
|
|
681
|
+
this.server.listen(port, host);
|
|
682
|
+
}
|
|
683
|
+
afterProgramCreate(program) {
|
|
684
|
+
// hijack the function to get workspace symbols, return a promise that resolves in the future
|
|
685
|
+
program.getWorkspaceSymbols = () => {
|
|
686
|
+
return this.deferred.promise;
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
defer() {
|
|
690
|
+
let resolve;
|
|
691
|
+
let reject;
|
|
692
|
+
let promise = new Promise((res, rej) => {
|
|
693
|
+
resolve = res;
|
|
694
|
+
reject = rej;
|
|
695
|
+
});
|
|
696
|
+
return {
|
|
697
|
+
resolve: resolve,
|
|
698
|
+
reject: reject,
|
|
699
|
+
promise: promise
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
const port = await getPort();
|
|
704
|
+
const host = '127.0.0.1';
|
|
705
|
+
//write a small brighterscript plugin to allow this test to communicate with the thread
|
|
706
|
+
fsExtra.outputFileSync(`${testHelpers_spec_1.rootDir}/plugin.js`, `
|
|
707
|
+
${Plugin.toString()};
|
|
708
|
+
exports.default = function() {
|
|
709
|
+
return new Plugin(${port}, "${host}");
|
|
710
|
+
};
|
|
711
|
+
`);
|
|
712
|
+
//write a bsconfig that will load this plugin
|
|
713
|
+
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
714
|
+
plugins: [
|
|
715
|
+
`${testHelpers_spec_1.rootDir}/plugin.js`
|
|
716
|
+
]
|
|
717
|
+
});
|
|
718
|
+
//wait for the projects to finish syncing/loading
|
|
719
|
+
await manager.syncProjects([{
|
|
720
|
+
workspaceFolder: testHelpers_spec_1.rootDir,
|
|
721
|
+
enableThreading: true
|
|
722
|
+
}]);
|
|
723
|
+
//establish the connection with the plugin
|
|
724
|
+
const connection = net.createConnection({
|
|
725
|
+
host: host,
|
|
726
|
+
port: port
|
|
727
|
+
});
|
|
728
|
+
//do the request to fetch symbols (this will be stalled on purpose by our test plugin)
|
|
729
|
+
let managerGetWorkspaceSymbolPromise = manager.getWorkspaceSymbol();
|
|
730
|
+
//small sleep to let things settle
|
|
731
|
+
await util_1.default.sleep(20);
|
|
732
|
+
//now dispose the project (which should destroy all of the listeners)
|
|
733
|
+
manager['removeProject'](manager.projects[0]);
|
|
734
|
+
//settle again
|
|
735
|
+
await util_1.default.sleep(20);
|
|
736
|
+
console.log('Asking the client to resolve');
|
|
737
|
+
//resolve the request
|
|
738
|
+
connection.write('resolve');
|
|
739
|
+
//now wait to see if we ever get the response back
|
|
740
|
+
let result = await managerGetWorkspaceSymbolPromise;
|
|
741
|
+
//the result should be an empty array, since the only project was rejected in the middle of the request
|
|
742
|
+
(0, chai_1.expect)(result).to.eql([]);
|
|
743
|
+
//test passes if the promise resolves
|
|
744
|
+
});
|
|
745
|
+
it('properly handles reloading when bsconfig.json contents change', async () => {
|
|
746
|
+
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
747
|
+
files: [
|
|
748
|
+
'one'
|
|
749
|
+
]
|
|
750
|
+
});
|
|
751
|
+
//wait for the projects to finish syncing/loading
|
|
752
|
+
await manager.syncProjects([{
|
|
753
|
+
workspaceFolder: testHelpers_spec_1.rootDir,
|
|
754
|
+
enableThreading: false
|
|
755
|
+
}]);
|
|
756
|
+
const stub = sinon.stub(manager, 'reloadProject').callThrough();
|
|
757
|
+
//change the file to new contents
|
|
758
|
+
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
759
|
+
files: [
|
|
760
|
+
'two'
|
|
761
|
+
]
|
|
762
|
+
});
|
|
763
|
+
await manager.handleFileChanges([{
|
|
764
|
+
srcPath: `${testHelpers_spec_1.rootDir}/bsconfig.json`,
|
|
765
|
+
type: vscode_languageserver_protocol_1.FileChangeType.Changed
|
|
766
|
+
}]);
|
|
767
|
+
//the project was reloaded
|
|
768
|
+
(0, chai_1.expect)(stub.callCount).to.eql(1);
|
|
769
|
+
//change the file to the same contents
|
|
770
|
+
fsExtra.outputJsonSync(`${testHelpers_spec_1.rootDir}/bsconfig.json`, {
|
|
771
|
+
files: [
|
|
772
|
+
'two'
|
|
773
|
+
]
|
|
774
|
+
});
|
|
775
|
+
await manager.handleFileChanges([{
|
|
776
|
+
srcPath: `${testHelpers_spec_1.rootDir}/bsconfig.json`,
|
|
777
|
+
type: vscode_languageserver_protocol_1.FileChangeType.Changed
|
|
778
|
+
}]);
|
|
779
|
+
//the project was not reloaded this time
|
|
780
|
+
(0, chai_1.expect)(stub.callCount).to.eql(1);
|
|
781
|
+
});
|
|
782
|
+
});
|
|
783
|
+
//# sourceMappingURL=ProjectManager.spec.js.map
|