@finos/legend-application-pure-ide 6.2.14

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.
Files changed (269) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +3 -0
  3. package/lib/application/LegendPureIDE.d.ts +26 -0
  4. package/lib/application/LegendPureIDE.d.ts.map +1 -0
  5. package/lib/application/LegendPureIDE.js +43 -0
  6. package/lib/application/LegendPureIDE.js.map +1 -0
  7. package/lib/application/LegendPureIDEApplicationConfig.d.ts +28 -0
  8. package/lib/application/LegendPureIDEApplicationConfig.d.ts.map +1 -0
  9. package/lib/application/LegendPureIDEApplicationConfig.js +30 -0
  10. package/lib/application/LegendPureIDEApplicationConfig.js.map +1 -0
  11. package/lib/application/LegendPureIDEPluginManager.d.ts +32 -0
  12. package/lib/application/LegendPureIDEPluginManager.d.ts.map +1 -0
  13. package/lib/application/LegendPureIDEPluginManager.js +46 -0
  14. package/lib/application/LegendPureIDEPluginManager.js.map +1 -0
  15. package/lib/components/Core_LegendPureIDEApplicationPlugin.d.ts +23 -0
  16. package/lib/components/Core_LegendPureIDEApplicationPlugin.d.ts.map +1 -0
  17. package/lib/components/Core_LegendPureIDEApplicationPlugin.js +29 -0
  18. package/lib/components/Core_LegendPureIDEApplicationPlugin.js.map +1 -0
  19. package/lib/components/LegendPureIDEApplication.d.ts +18 -0
  20. package/lib/components/LegendPureIDEApplication.d.ts.map +1 -0
  21. package/lib/components/LegendPureIDEApplication.js +21 -0
  22. package/lib/components/LegendPureIDEApplication.js.map +1 -0
  23. package/lib/components/LegendPureIDEBaseStoreProvider.d.ts +23 -0
  24. package/lib/components/LegendPureIDEBaseStoreProvider.d.ts.map +1 -0
  25. package/lib/components/LegendPureIDEBaseStoreProvider.js +30 -0
  26. package/lib/components/LegendPureIDEBaseStoreProvider.js.map +1 -0
  27. package/lib/components/editor/ActivityBar.d.ts +20 -0
  28. package/lib/components/editor/ActivityBar.d.ts.map +1 -0
  29. package/lib/components/editor/ActivityBar.js +41 -0
  30. package/lib/components/editor/ActivityBar.js.map +1 -0
  31. package/lib/components/editor/Editor.d.ts +18 -0
  32. package/lib/components/editor/Editor.d.ts.map +1 -0
  33. package/lib/components/editor/Editor.js +80 -0
  34. package/lib/components/editor/Editor.js.map +1 -0
  35. package/lib/components/editor/EditorStoreProvider.d.ts +22 -0
  36. package/lib/components/editor/EditorStoreProvider.d.ts.map +1 -0
  37. package/lib/components/editor/EditorStoreProvider.js +32 -0
  38. package/lib/components/editor/EditorStoreProvider.js.map +1 -0
  39. package/lib/components/editor/StatusBar.d.ts +22 -0
  40. package/lib/components/editor/StatusBar.d.ts.map +1 -0
  41. package/lib/components/editor/StatusBar.js +39 -0
  42. package/lib/components/editor/StatusBar.js.map +1 -0
  43. package/lib/components/editor/aux-panel/AuxiliaryPanel.d.ts +20 -0
  44. package/lib/components/editor/aux-panel/AuxiliaryPanel.d.ts.map +1 -0
  45. package/lib/components/editor/aux-panel/AuxiliaryPanel.js +65 -0
  46. package/lib/components/editor/aux-panel/AuxiliaryPanel.js.map +1 -0
  47. package/lib/components/editor/aux-panel/ConsolePanel.d.ts +20 -0
  48. package/lib/components/editor/aux-panel/ConsolePanel.d.ts.map +1 -0
  49. package/lib/components/editor/aux-panel/ConsolePanel.js +24 -0
  50. package/lib/components/editor/aux-panel/ConsolePanel.js.map +1 -0
  51. package/lib/components/editor/aux-panel/SearchPanel.d.ts +20 -0
  52. package/lib/components/editor/aux-panel/SearchPanel.d.ts.map +1 -0
  53. package/lib/components/editor/aux-panel/SearchPanel.js +90 -0
  54. package/lib/components/editor/aux-panel/SearchPanel.js.map +1 -0
  55. package/lib/components/editor/aux-panel/TestRunnerPanel.d.ts +20 -0
  56. package/lib/components/editor/aux-panel/TestRunnerPanel.d.ts.map +1 -0
  57. package/lib/components/editor/aux-panel/TestRunnerPanel.js +151 -0
  58. package/lib/components/editor/aux-panel/TestRunnerPanel.js.map +1 -0
  59. package/lib/components/editor/command-center/CreateNewDirectoryCommand.d.ts +20 -0
  60. package/lib/components/editor/command-center/CreateNewDirectoryCommand.d.ts.map +1 -0
  61. package/lib/components/editor/command-center/CreateNewDirectoryCommand.js +48 -0
  62. package/lib/components/editor/command-center/CreateNewDirectoryCommand.js.map +1 -0
  63. package/lib/components/editor/command-center/CreateNewFileCommand.d.ts +20 -0
  64. package/lib/components/editor/command-center/CreateNewFileCommand.d.ts.map +1 -0
  65. package/lib/components/editor/command-center/CreateNewFileCommand.js +48 -0
  66. package/lib/components/editor/command-center/CreateNewFileCommand.js.map +1 -0
  67. package/lib/components/editor/command-center/FileSearchCommand.d.ts +20 -0
  68. package/lib/components/editor/command-center/FileSearchCommand.d.ts.map +1 -0
  69. package/lib/components/editor/command-center/FileSearchCommand.js +60 -0
  70. package/lib/components/editor/command-center/FileSearchCommand.js.map +1 -0
  71. package/lib/components/editor/command-center/TextSearchCommand.d.ts +20 -0
  72. package/lib/components/editor/command-center/TextSearchCommand.d.ts.map +1 -0
  73. package/lib/components/editor/command-center/TextSearchCommand.js +50 -0
  74. package/lib/components/editor/command-center/TextSearchCommand.js.map +1 -0
  75. package/lib/components/editor/edit-panel/DiagramEditor.d.ts +23 -0
  76. package/lib/components/editor/edit-panel/DiagramEditor.d.ts.map +1 -0
  77. package/lib/components/editor/edit-panel/DiagramEditor.js +71 -0
  78. package/lib/components/editor/edit-panel/DiagramEditor.js.map +1 -0
  79. package/lib/components/editor/edit-panel/EditPanel.d.ts +21 -0
  80. package/lib/components/editor/edit-panel/EditPanel.d.ts.map +1 -0
  81. package/lib/components/editor/edit-panel/EditPanel.js +55 -0
  82. package/lib/components/editor/edit-panel/EditPanel.js.map +1 -0
  83. package/lib/components/editor/edit-panel/FileEditor.d.ts +23 -0
  84. package/lib/components/editor/edit-panel/FileEditor.d.ts.map +1 -0
  85. package/lib/components/editor/edit-panel/FileEditor.js +114 -0
  86. package/lib/components/editor/edit-panel/FileEditor.js.map +1 -0
  87. package/lib/components/editor/shared/ConceptIconUtils.d.ts +17 -0
  88. package/lib/components/editor/shared/ConceptIconUtils.d.ts.map +1 -0
  89. package/lib/components/editor/shared/ConceptIconUtils.js +50 -0
  90. package/lib/components/editor/shared/ConceptIconUtils.js.map +1 -0
  91. package/lib/components/editor/side-bar/ConceptTreeExplorer.d.ts +24 -0
  92. package/lib/components/editor/side-bar/ConceptTreeExplorer.d.ts.map +1 -0
  93. package/lib/components/editor/side-bar/ConceptTreeExplorer.js +165 -0
  94. package/lib/components/editor/side-bar/ConceptTreeExplorer.js.map +1 -0
  95. package/lib/components/editor/side-bar/DirectoryTreeExplorer.d.ts +20 -0
  96. package/lib/components/editor/side-bar/DirectoryTreeExplorer.d.ts.map +1 -0
  97. package/lib/components/editor/side-bar/DirectoryTreeExplorer.js +142 -0
  98. package/lib/components/editor/side-bar/DirectoryTreeExplorer.js.map +1 -0
  99. package/lib/components/editor/side-bar/SideBar.d.ts +23 -0
  100. package/lib/components/editor/side-bar/SideBar.d.ts.map +1 -0
  101. package/lib/components/editor/side-bar/SideBar.js +40 -0
  102. package/lib/components/editor/side-bar/SideBar.js.map +1 -0
  103. package/lib/extensions.css +17 -0
  104. package/lib/extensions.css.map +1 -0
  105. package/lib/index.css +17 -0
  106. package/lib/index.css.map +1 -0
  107. package/lib/index.d.ts +22 -0
  108. package/lib/index.d.ts.map +1 -0
  109. package/lib/index.js +39 -0
  110. package/lib/index.js.map +1 -0
  111. package/lib/package.json +85 -0
  112. package/lib/server/PureServerClient.d.ts +55 -0
  113. package/lib/server/PureServerClient.d.ts.map +1 -0
  114. package/lib/server/PureServerClient.js +120 -0
  115. package/lib/server/PureServerClient.js.map +1 -0
  116. package/lib/server/models/Command.d.ts +24 -0
  117. package/lib/server/models/Command.d.ts.map +1 -0
  118. package/lib/server/models/Command.js +35 -0
  119. package/lib/server/models/Command.js.map +1 -0
  120. package/lib/server/models/ConceptTree.d.ts +76 -0
  121. package/lib/server/models/ConceptTree.d.ts.map +1 -0
  122. package/lib/server/models/ConceptTree.js +116 -0
  123. package/lib/server/models/ConceptTree.js.map +1 -0
  124. package/lib/server/models/DiagramInfo.d.ts +144 -0
  125. package/lib/server/models/DiagramInfo.d.ts.map +1 -0
  126. package/lib/server/models/DiagramInfo.js +478 -0
  127. package/lib/server/models/DiagramInfo.js.map +1 -0
  128. package/lib/server/models/DirectoryTree.d.ts +37 -0
  129. package/lib/server/models/DirectoryTree.d.ts.map +1 -0
  130. package/lib/server/models/DirectoryTree.js +70 -0
  131. package/lib/server/models/DirectoryTree.js.map +1 -0
  132. package/lib/server/models/Execution.d.ts +100 -0
  133. package/lib/server/models/Execution.d.ts.map +1 -0
  134. package/lib/server/models/Execution.js +183 -0
  135. package/lib/server/models/Execution.js.map +1 -0
  136. package/lib/server/models/Initialization.d.ts +49 -0
  137. package/lib/server/models/Initialization.d.ts.map +1 -0
  138. package/lib/server/models/Initialization.js +64 -0
  139. package/lib/server/models/Initialization.js.map +1 -0
  140. package/lib/server/models/PureFile.d.ts +34 -0
  141. package/lib/server/models/PureFile.d.ts.map +1 -0
  142. package/lib/server/models/PureFile.js +56 -0
  143. package/lib/server/models/PureFile.js.map +1 -0
  144. package/lib/server/models/SearchEntry.d.ts +36 -0
  145. package/lib/server/models/SearchEntry.d.ts.map +1 -0
  146. package/lib/server/models/SearchEntry.js +63 -0
  147. package/lib/server/models/SearchEntry.js.map +1 -0
  148. package/lib/server/models/SourceInformation.d.ts +25 -0
  149. package/lib/server/models/SourceInformation.d.ts.map +1 -0
  150. package/lib/server/models/SourceInformation.js +35 -0
  151. package/lib/server/models/SourceInformation.js.map +1 -0
  152. package/lib/server/models/Test.d.ts +57 -0
  153. package/lib/server/models/Test.d.ts.map +1 -0
  154. package/lib/server/models/Test.js +92 -0
  155. package/lib/server/models/Test.js.map +1 -0
  156. package/lib/server/models/Usage.d.ts +31 -0
  157. package/lib/server/models/Usage.d.ts.map +1 -0
  158. package/lib/server/models/Usage.js +36 -0
  159. package/lib/server/models/Usage.js.map +1 -0
  160. package/lib/stores/ConceptTreeState.d.ts +34 -0
  161. package/lib/stores/ConceptTreeState.d.ts.map +1 -0
  162. package/lib/stores/ConceptTreeState.js +117 -0
  163. package/lib/stores/ConceptTreeState.js.map +1 -0
  164. package/lib/stores/DiagramEditorState.d.ts +40 -0
  165. package/lib/stores/DiagramEditorState.d.ts.map +1 -0
  166. package/lib/stores/DiagramEditorState.js +90 -0
  167. package/lib/stores/DiagramEditorState.js.map +1 -0
  168. package/lib/stores/DirectoryTreeState.d.ts +35 -0
  169. package/lib/stores/DirectoryTreeState.d.ts.map +1 -0
  170. package/lib/stores/DirectoryTreeState.js +119 -0
  171. package/lib/stores/DirectoryTreeState.js.map +1 -0
  172. package/lib/stores/EditorConfig.d.ts +25 -0
  173. package/lib/stores/EditorConfig.d.ts.map +1 -0
  174. package/lib/stores/EditorConfig.js +27 -0
  175. package/lib/stores/EditorConfig.js.map +1 -0
  176. package/lib/stores/EditorStore.d.ts +102 -0
  177. package/lib/stores/EditorStore.d.ts.map +1 -0
  178. package/lib/stores/EditorStore.js +761 -0
  179. package/lib/stores/EditorStore.js.map +1 -0
  180. package/lib/stores/EditorTabManagerState.d.ts +31 -0
  181. package/lib/stores/EditorTabManagerState.d.ts.map +1 -0
  182. package/lib/stores/EditorTabManagerState.js +62 -0
  183. package/lib/stores/EditorTabManagerState.js.map +1 -0
  184. package/lib/stores/FileEditorState.d.ts +37 -0
  185. package/lib/stores/FileEditorState.d.ts.map +1 -0
  186. package/lib/stores/FileEditorState.js +99 -0
  187. package/lib/stores/FileEditorState.js.map +1 -0
  188. package/lib/stores/LegendPureIDEApplicationPlugin.d.ts +26 -0
  189. package/lib/stores/LegendPureIDEApplicationPlugin.d.ts.map +1 -0
  190. package/lib/stores/LegendPureIDEApplicationPlugin.js +27 -0
  191. package/lib/stores/LegendPureIDEApplicationPlugin.js.map +1 -0
  192. package/lib/stores/LegendPureIDEBaseStore.d.ts +25 -0
  193. package/lib/stores/LegendPureIDEBaseStore.d.ts.map +1 -0
  194. package/lib/stores/LegendPureIDEBaseStore.js +25 -0
  195. package/lib/stores/LegendPureIDEBaseStore.js.map +1 -0
  196. package/lib/stores/LegendPureIDECommand.d.ts +32 -0
  197. package/lib/stores/LegendPureIDECommand.d.ts.map +1 -0
  198. package/lib/stores/LegendPureIDECommand.js +82 -0
  199. package/lib/stores/LegendPureIDECommand.js.map +1 -0
  200. package/lib/stores/SearchCommandState.d.ts +28 -0
  201. package/lib/stores/SearchCommandState.d.ts.map +1 -0
  202. package/lib/stores/SearchCommandState.js +53 -0
  203. package/lib/stores/SearchCommandState.js.map +1 -0
  204. package/lib/stores/SearchResultState.d.ts +43 -0
  205. package/lib/stores/SearchResultState.d.ts.map +1 -0
  206. package/lib/stores/SearchResultState.js +92 -0
  207. package/lib/stores/SearchResultState.js.map +1 -0
  208. package/lib/stores/TestRunnerState.d.ts +87 -0
  209. package/lib/stores/TestRunnerState.d.ts.map +1 -0
  210. package/lib/stores/TestRunnerState.js +336 -0
  211. package/lib/stores/TestRunnerState.js.map +1 -0
  212. package/lib/stores/TreeState.d.ts +42 -0
  213. package/lib/stores/TreeState.d.ts.map +1 -0
  214. package/lib/stores/TreeState.js +139 -0
  215. package/lib/stores/TreeState.js.map +1 -0
  216. package/package.json +85 -0
  217. package/src/application/LegendPureIDE.tsx +73 -0
  218. package/src/application/LegendPureIDEApplicationConfig.ts +58 -0
  219. package/src/application/LegendPureIDEPluginManager.ts +67 -0
  220. package/src/components/Core_LegendPureIDEApplicationPlugin.tsx +37 -0
  221. package/src/components/LegendPureIDEApplication.tsx +27 -0
  222. package/src/components/LegendPureIDEBaseStoreProvider.tsx +57 -0
  223. package/src/components/editor/ActivityBar.tsx +74 -0
  224. package/src/components/editor/Editor.tsx +180 -0
  225. package/src/components/editor/EditorStoreProvider.tsx +57 -0
  226. package/src/components/editor/StatusBar.tsx +95 -0
  227. package/src/components/editor/aux-panel/AuxiliaryPanel.tsx +155 -0
  228. package/src/components/editor/aux-panel/ConsolePanel.tsx +49 -0
  229. package/src/components/editor/aux-panel/SearchPanel.tsx +421 -0
  230. package/src/components/editor/aux-panel/TestRunnerPanel.tsx +455 -0
  231. package/src/components/editor/command-center/CreateNewDirectoryCommand.tsx +86 -0
  232. package/src/components/editor/command-center/CreateNewFileCommand.tsx +84 -0
  233. package/src/components/editor/command-center/FileSearchCommand.tsx +112 -0
  234. package/src/components/editor/command-center/TextSearchCommand.tsx +103 -0
  235. package/src/components/editor/edit-panel/DiagramEditor.tsx +108 -0
  236. package/src/components/editor/edit-panel/EditPanel.tsx +114 -0
  237. package/src/components/editor/edit-panel/FileEditor.tsx +156 -0
  238. package/src/components/editor/shared/ConceptIconUtils.tsx +78 -0
  239. package/src/components/editor/side-bar/ConceptTreeExplorer.tsx +401 -0
  240. package/src/components/editor/side-bar/DirectoryTreeExplorer.tsx +366 -0
  241. package/src/components/editor/side-bar/SideBar.tsx +51 -0
  242. package/src/index.tsx +46 -0
  243. package/src/server/PureServerClient.ts +299 -0
  244. package/src/server/models/Command.ts +40 -0
  245. package/src/server/models/ConceptTree.ts +152 -0
  246. package/src/server/models/DiagramInfo.ts +793 -0
  247. package/src/server/models/DirectoryTree.ts +100 -0
  248. package/src/server/models/Execution.ts +223 -0
  249. package/src/server/models/Initialization.ts +92 -0
  250. package/src/server/models/PureFile.ts +76 -0
  251. package/src/server/models/SearchEntry.ts +85 -0
  252. package/src/server/models/SourceInformation.ts +37 -0
  253. package/src/server/models/Test.ts +125 -0
  254. package/src/server/models/Usage.ts +49 -0
  255. package/src/stores/ConceptTreeState.ts +156 -0
  256. package/src/stores/DiagramEditorState.ts +150 -0
  257. package/src/stores/DirectoryTreeState.ts +168 -0
  258. package/src/stores/EditorConfig.ts +26 -0
  259. package/src/stores/EditorStore.ts +1087 -0
  260. package/src/stores/EditorTabManagerState.ts +74 -0
  261. package/src/stores/FileEditorState.ts +148 -0
  262. package/src/stores/LegendPureIDEApplicationPlugin.ts +30 -0
  263. package/src/stores/LegendPureIDEBaseStore.ts +36 -0
  264. package/src/stores/LegendPureIDECommand.ts +84 -0
  265. package/src/stores/SearchCommandState.ts +61 -0
  266. package/src/stores/SearchResultState.ts +131 -0
  267. package/src/stores/TestRunnerState.ts +470 -0
  268. package/src/stores/TreeState.ts +179 -0
  269. package/tsconfig.json +98 -0
@@ -0,0 +1,470 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import {
18
+ action,
19
+ computed,
20
+ flow,
21
+ flowResult,
22
+ makeObservable,
23
+ observable,
24
+ } from 'mobx';
25
+ import type { TreeData, TreeNodeData } from '@finos/legend-art';
26
+ import {
27
+ type GeneratorFn,
28
+ ActionState,
29
+ addUniqueEntry,
30
+ assertErrorThrown,
31
+ assertTrue,
32
+ guaranteeNonNullable,
33
+ guaranteeType,
34
+ promisify,
35
+ UnsupportedOperationError,
36
+ } from '@finos/legend-shared';
37
+ import type {
38
+ TestExecutionResult,
39
+ TestInfo,
40
+ } from '../server/models/Execution.js';
41
+ import {
42
+ type TestResult,
43
+ deserializeTestRunnerCheckResult,
44
+ TestFailureResult,
45
+ TestResultStatus,
46
+ TestRunnerCheckResult,
47
+ } from '../server/models/Test.js';
48
+ import type { EditorStore } from '../stores/EditorStore.js';
49
+
50
+ const getFullParentId = (
51
+ testInfo: TestInfo,
52
+ testExecutionResult: TestExecutionResult,
53
+ ): string => `test${testExecutionResult.runnerId}_${testInfo.li_attr.parentId}`;
54
+ const getFullTestId = (
55
+ testResult: TestResult,
56
+ testExecutionResult: TestExecutionResult,
57
+ ): string => `test${testExecutionResult.runnerId}_${testResult.test.join('_')}`;
58
+
59
+ export interface TestTreeNode extends TreeNodeData {
60
+ data: TestInfo;
61
+ isLoading: boolean;
62
+ }
63
+
64
+ export enum TestSuiteStatus {
65
+ PASSED = 'PASSED',
66
+ FAILED = 'FAILED',
67
+ NONE = 'NONE',
68
+ }
69
+
70
+ export enum TestResultType {
71
+ PASSED = 'PASSED',
72
+ FAILED = 'FAILED',
73
+ ERROR = 'ERROR',
74
+ RUNNING = 'RUNNING',
75
+ }
76
+
77
+ export const getTestResultById = (
78
+ id: string,
79
+ testResultInfo: TestResultInfo,
80
+ ): TestResultType =>
81
+ testResultInfo.passedTests.has(id)
82
+ ? TestResultType.PASSED
83
+ : testResultInfo.failedTests.has(id)
84
+ ? TestResultType.FAILED
85
+ : testResultInfo.testsWithError.has(id)
86
+ ? TestResultType.ERROR
87
+ : TestResultType.RUNNING;
88
+
89
+ export const getTestTreeNodeStatus = (
90
+ node: TestTreeNode,
91
+ testResultInfo: TestResultInfo,
92
+ ): TestResultType => {
93
+ const id = node.id;
94
+ const isLeafNode = Boolean(node.data.type);
95
+ if (isLeafNode) {
96
+ return getTestResultById(id, testResultInfo);
97
+ }
98
+ // order matters here, also if one test fail/error the whole sub-tree (package) will be marked as failed
99
+ return testResultInfo.failedTestIds.some((i) => i.startsWith(id)) ||
100
+ testResultInfo.testWithErrorIds.some((i) => i.startsWith(id))
101
+ ? TestResultType.FAILED
102
+ : testResultInfo.notRunTestIds.some((i) => i.startsWith(id))
103
+ ? TestResultType.RUNNING
104
+ : TestResultType.PASSED;
105
+ };
106
+
107
+ export class TestResultInfo {
108
+ private readonly _START_TIME: number;
109
+ total!: number;
110
+ time = 0; // ms
111
+ passedTests = new Set<string>();
112
+ failedTests = new Map<string, TestFailureResult>();
113
+ testsWithError = new Map<string, TestFailureResult>();
114
+ notRunTests: Set<string>;
115
+ results = new Map<string, TestResult>();
116
+
117
+ constructor(allTestIds: Set<string>) {
118
+ makeObservable(this, {
119
+ total: observable,
120
+ time: observable,
121
+ passedTests: observable,
122
+ failedTests: observable,
123
+ testsWithError: observable,
124
+ notRunTests: observable,
125
+ results: observable,
126
+ passed: computed,
127
+ error: computed,
128
+ failed: computed,
129
+ passedTestIds: computed,
130
+ failedTestIds: computed,
131
+ testWithErrorIds: computed,
132
+ notRunTestIds: computed,
133
+ numberOfTestsRun: computed,
134
+ runPercentage: computed,
135
+ suiteStatus: computed,
136
+ setTime: action,
137
+ addResult: action,
138
+ });
139
+
140
+ this._START_TIME = Date.now();
141
+ this.total = allTestIds.size;
142
+ this.notRunTests = new Set(allTestIds);
143
+ }
144
+
145
+ get passed(): number {
146
+ return this.passedTests.size;
147
+ }
148
+
149
+ get error(): number {
150
+ return this.testsWithError.size;
151
+ }
152
+
153
+ get failed(): number {
154
+ return this.failedTests.size;
155
+ }
156
+
157
+ get passedTestIds(): string[] {
158
+ return Array.from(this.passedTests.values());
159
+ }
160
+
161
+ get failedTestIds(): string[] {
162
+ return Array.from(this.failedTests.keys());
163
+ }
164
+
165
+ get testWithErrorIds(): string[] {
166
+ return Array.from(this.testsWithError.keys());
167
+ }
168
+
169
+ get notRunTestIds(): string[] {
170
+ return Array.from(this.notRunTests.values());
171
+ }
172
+
173
+ get numberOfTestsRun(): number {
174
+ return this.passed + this.error + this.failed;
175
+ }
176
+
177
+ get runPercentage(): number {
178
+ return Math.floor((this.numberOfTestsRun * 100) / this.total);
179
+ }
180
+
181
+ get suiteStatus(): TestSuiteStatus {
182
+ return this.failed + this.error
183
+ ? TestSuiteStatus.FAILED
184
+ : this.passed
185
+ ? TestSuiteStatus.PASSED
186
+ : TestSuiteStatus.NONE;
187
+ }
188
+
189
+ setTime(val: number): void {
190
+ this.time = val;
191
+ }
192
+
193
+ addResult(result: TestResult, testId: string): void {
194
+ this.results.set(testId, result);
195
+ this.notRunTests.delete(testId);
196
+ switch (result.status) {
197
+ case TestResultStatus.PASSED: {
198
+ this.passedTests.add(testId);
199
+ break;
200
+ }
201
+ case TestResultStatus.FAILED: {
202
+ this.failedTests.set(testId, guaranteeType(result, TestFailureResult));
203
+ break;
204
+ }
205
+ case TestResultStatus.ERROR: {
206
+ this.testsWithError.set(
207
+ testId,
208
+ guaranteeType(result, TestFailureResult),
209
+ );
210
+ break;
211
+ }
212
+ default: {
213
+ throw new UnsupportedOperationError(
214
+ `Unsupported test result status '${result.status}'`,
215
+ );
216
+ }
217
+ }
218
+ this.time = Date.now() - this._START_TIME;
219
+ }
220
+ }
221
+
222
+ export class TestRunnerState {
223
+ readonly editorStore: EditorStore;
224
+ readonly testExecutionResult: TestExecutionResult;
225
+
226
+ readonly checkTestRunnerState = ActionState.create();
227
+ testResultInfo?: TestResultInfo | undefined;
228
+ allTests = new Map<string, TestInfo>();
229
+ selectedTestId?: string | undefined;
230
+
231
+ // explorer tree
232
+ readonly treeBuildingState = ActionState.create();
233
+ selectedNode?: TestTreeNode | undefined;
234
+ treeData?: TreeData<TestTreeNode> | undefined;
235
+
236
+ constructor(
237
+ editorStore: EditorStore,
238
+ testExecutionResult: TestExecutionResult,
239
+ ) {
240
+ makeObservable(this, {
241
+ testResultInfo: observable.ref,
242
+ allTests: observable,
243
+ selectedTestId: observable,
244
+ selectedNode: observable,
245
+ treeData: observable.ref,
246
+ setSelectedTestId: action,
247
+ setTestResultInfo: action,
248
+ setTreeData: action,
249
+ refreshTree: action,
250
+ setSelectedNode: action,
251
+ collapseTree: action,
252
+ expandTree: action,
253
+ buildTreeDataByLayer: action,
254
+ pullTestRunnerResult: action,
255
+ buildTestTreeData: flow,
256
+ pollTestRunnerResult: flow,
257
+ rerunTestSuite: flow,
258
+ cancelTestRun: flow,
259
+ });
260
+
261
+ this.editorStore = editorStore;
262
+ this.testExecutionResult = testExecutionResult;
263
+ }
264
+
265
+ getTreeData(): TreeData<TestTreeNode> {
266
+ return guaranteeNonNullable(
267
+ this.treeData,
268
+ 'Test tree data has not been initialized',
269
+ );
270
+ }
271
+
272
+ setSelectedTestId(val: string | undefined): void {
273
+ this.selectedTestId = val;
274
+ }
275
+
276
+ setTestResultInfo(val: TestResultInfo | undefined): void {
277
+ this.testResultInfo = val;
278
+ }
279
+
280
+ setTreeData(data: TreeData<TestTreeNode>): void {
281
+ this.treeData = data;
282
+ }
283
+
284
+ refreshTree(): void {
285
+ this.setTreeData({ ...guaranteeNonNullable(this.treeData) });
286
+ }
287
+
288
+ setSelectedNode(node: TestTreeNode | undefined): void {
289
+ if (node?.id !== this.selectedNode?.id) {
290
+ if (this.selectedNode) {
291
+ this.selectedNode.isSelected = false;
292
+ }
293
+ if (node) {
294
+ node.isSelected = true;
295
+ }
296
+ this.selectedNode = node;
297
+ this.refreshTree();
298
+ }
299
+ }
300
+
301
+ *buildTestTreeData(): GeneratorFn<void> {
302
+ if (this.treeBuildingState.isInProgress) {
303
+ return;
304
+ }
305
+ this.treeBuildingState.inProgress();
306
+ const rootIds = this.testExecutionResult.tests.map((test) => {
307
+ const id = test.li_attr.id;
308
+ if (test.type) {
309
+ this.allTests.set(id, test);
310
+ }
311
+ return id;
312
+ });
313
+ const nodes = new Map<string, TestTreeNode>();
314
+ this.treeData = { rootIds, nodes };
315
+ yield this.buildTreeDataByLayer(this.testExecutionResult.tests);
316
+ this.treeBuildingState.reset();
317
+ }
318
+
319
+ collapseTree(): void {
320
+ const treeData = this.getTreeData();
321
+ treeData.nodes.forEach((node) => {
322
+ node.isOpen = false;
323
+ });
324
+ this.setSelectedNode(undefined);
325
+ this.refreshTree();
326
+ }
327
+
328
+ expandTree(): void {
329
+ const treeData = this.getTreeData();
330
+ treeData.nodes.forEach((node) => {
331
+ node.isOpen = true;
332
+ });
333
+ this.setSelectedNode(undefined);
334
+ this.refreshTree();
335
+ }
336
+
337
+ async buildTreeDataByLayer(tests: TestInfo[]): Promise<void> {
338
+ const treeData = this.getTreeData();
339
+ const childLevelTests: TestInfo[] = [];
340
+ await Promise.all(
341
+ tests.map(
342
+ (test) =>
343
+ new Promise<void>((resolve, reject) =>
344
+ setTimeout(() => {
345
+ const id = test.li_attr.id;
346
+ const node = {
347
+ id: id,
348
+ label: test.text,
349
+ data: test,
350
+ childrenIds: test.type ? undefined : [],
351
+ isLoading: false,
352
+ };
353
+ if (test.type) {
354
+ this.allTests.set(id, test);
355
+ }
356
+ treeData.nodes.set(id, node);
357
+ if (test.li_attr.parentId !== 'Root') {
358
+ try {
359
+ const parentNode = guaranteeNonNullable(
360
+ treeData.nodes.get(
361
+ getFullParentId(test, this.testExecutionResult),
362
+ ),
363
+ `Can't find parent test node with ID '${test.li_attr.parentId}'`,
364
+ );
365
+ if (parentNode.childrenIds) {
366
+ addUniqueEntry(parentNode.childrenIds, id);
367
+ } else {
368
+ parentNode.childrenIds = [id];
369
+ }
370
+ } catch (error) {
371
+ reject(error);
372
+ return;
373
+ }
374
+ }
375
+ childLevelTests.push(...test.children);
376
+ resolve();
377
+ }, 0),
378
+ ),
379
+ ),
380
+ );
381
+ if (childLevelTests.length) {
382
+ return this.buildTreeDataByLayer(childLevelTests);
383
+ }
384
+ return Promise.resolve();
385
+ }
386
+
387
+ *pollTestRunnerResult(): GeneratorFn<void> {
388
+ if (!this.checkTestRunnerState.isInInitialState) {
389
+ return;
390
+ }
391
+ this.checkTestRunnerState.inProgress();
392
+ try {
393
+ assertTrue(
394
+ this.allTests.size === this.testExecutionResult.count,
395
+ `Number of tests scanned in tree (${this.allTests.size}) does not match the number of total reported tests (${this.testExecutionResult.count})`,
396
+ );
397
+ const testResultInfo = new TestResultInfo(new Set(this.allTests.keys()));
398
+ this.testResultInfo = testResultInfo;
399
+ yield this.pullTestRunnerResult(testResultInfo);
400
+ } finally {
401
+ this.checkTestRunnerState.reset();
402
+ }
403
+ }
404
+
405
+ async pullTestRunnerResult(testResultInfo: TestResultInfo): Promise<void> {
406
+ const result = deserializeTestRunnerCheckResult(
407
+ await this.editorStore.client.checkTestRunner(
408
+ this.testExecutionResult.runnerId,
409
+ ),
410
+ );
411
+ if (result instanceof TestRunnerCheckResult) {
412
+ await Promise.all(
413
+ result.tests.map((test) =>
414
+ promisify(() =>
415
+ testResultInfo.addResult(
416
+ test,
417
+ getFullTestId(test, this.testExecutionResult),
418
+ ),
419
+ ),
420
+ ),
421
+ );
422
+ if (!result.finished) {
423
+ return new Promise((resolve, reject) =>
424
+ setTimeout(() => {
425
+ try {
426
+ resolve(this.pullTestRunnerResult(testResultInfo));
427
+ } catch (error) {
428
+ assertErrorThrown(error);
429
+ this.editorStore.applicationStore.notifyWarning(
430
+ `Failed to run test${
431
+ error.message ? `: ${error.message}` : ''
432
+ }`,
433
+ );
434
+ reject(error);
435
+ }
436
+ // NOTE: this call might take a while so we need to tune this depending on the performance of the app
437
+ }, 1000),
438
+ );
439
+ }
440
+ return Promise.resolve();
441
+ }
442
+ // test runner check error -> runner has been cancelled
443
+ this.setTestResultInfo(undefined);
444
+ return Promise.resolve();
445
+ }
446
+
447
+ *rerunTestSuite(): GeneratorFn<void> {
448
+ if (this.editorStore.testRunState.isInProgress) {
449
+ return;
450
+ }
451
+ yield flowResult(
452
+ this.editorStore.executeTests(
453
+ this.testExecutionResult.path,
454
+ this.testExecutionResult.relevantTestsOnly,
455
+ ),
456
+ );
457
+ }
458
+
459
+ *cancelTestRun(): GeneratorFn<void> {
460
+ if (!this.editorStore.testRunState.isInProgress) {
461
+ return;
462
+ }
463
+ yield this.editorStore.client.cancelTestRunner(
464
+ this.testExecutionResult.runnerId,
465
+ );
466
+ this.editorStore.applicationStore.notifyWarning(
467
+ `Stopped running test (id: ${this.testExecutionResult.runnerId}) successfully!`,
468
+ );
469
+ }
470
+ }
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import type { TreeData, TreeNodeData } from '@finos/legend-art';
18
+ import {
19
+ type GeneratorFn,
20
+ ActionState,
21
+ assertErrorThrown,
22
+ guaranteeNonNullable,
23
+ } from '@finos/legend-shared';
24
+ import { action, observable, makeObservable, flow, flowResult } from 'mobx';
25
+ import type { EditorStore } from './EditorStore.js';
26
+
27
+ export abstract class TreeState<
28
+ T extends TreeNodeData & { isLoading: boolean },
29
+ V,
30
+ > {
31
+ readonly editorStore: EditorStore;
32
+
33
+ treeData?: TreeData<T>;
34
+ selectedNode?: T | undefined;
35
+ loadInitialDataState = ActionState.create();
36
+ refreshDataState = ActionState.create();
37
+
38
+ constructor(editorStore: EditorStore) {
39
+ makeObservable(this, {
40
+ treeData: observable.ref,
41
+ loadInitialDataState: observable,
42
+ refreshDataState: observable,
43
+ initialize: flow,
44
+ expandNode: flow,
45
+ openNode: flow,
46
+ refreshTreeData: flow,
47
+ setTreeData: action,
48
+ setSelectedNode: action,
49
+ });
50
+
51
+ this.editorStore = editorStore;
52
+ }
53
+
54
+ getTreeData(): TreeData<T> {
55
+ return guaranteeNonNullable(
56
+ this.treeData,
57
+ 'Tree data has not been initialized',
58
+ );
59
+ }
60
+
61
+ abstract getRootNodes(): Promise<V[]>;
62
+ abstract buildTreeData(rootNodes: V[]): TreeData<T>;
63
+ abstract getChildNodes(node: T): Promise<V[]>;
64
+ abstract processChildNodes(node: T, childNodes: V[]): void;
65
+
66
+ *initialize(): GeneratorFn<void> {
67
+ if (this.loadInitialDataState.isInProgress) {
68
+ this.editorStore.applicationStore.notifyWarning(
69
+ 'Tree state initialization is in progress',
70
+ );
71
+ return;
72
+ }
73
+ this.loadInitialDataState.inProgress();
74
+ try {
75
+ this.treeData = this.buildTreeData((yield this.getRootNodes()) as V[]);
76
+ this.loadInitialDataState.pass();
77
+ } catch (error) {
78
+ assertErrorThrown(error);
79
+ this.editorStore.applicationStore.notifyError(error);
80
+ this.loadInitialDataState.fail();
81
+ }
82
+ }
83
+
84
+ setSelectedNode(node: T | undefined): void {
85
+ if (node !== this.selectedNode) {
86
+ if (this.selectedNode) {
87
+ this.selectedNode.isSelected = false;
88
+ }
89
+ if (node) {
90
+ node.isSelected = true;
91
+ }
92
+ this.selectedNode = node;
93
+ this.refreshTree();
94
+ }
95
+ }
96
+ setTreeData(data: TreeData<T>): void {
97
+ this.treeData = data;
98
+ }
99
+ refreshTree(): void {
100
+ this.setTreeData({ ...guaranteeNonNullable(this.treeData) });
101
+ }
102
+
103
+ abstract openNode(node: T): GeneratorFn<void>;
104
+
105
+ *expandNode(node: T): GeneratorFn<void> {
106
+ if (node.isLoading) {
107
+ return;
108
+ }
109
+ if (this.getTreeData().nodes.has(node.id) && node.childrenIds) {
110
+ node.isLoading = false;
111
+ node.isOpen = true;
112
+ this.refreshTree();
113
+ } else {
114
+ node.isLoading = true;
115
+ try {
116
+ const childNodes = (yield this.getChildNodes(node)) as V[];
117
+ this.processChildNodes(node, childNodes);
118
+ node.isOpen = true;
119
+ this.refreshTree();
120
+ } catch (error) {
121
+ assertErrorThrown(error);
122
+ this.editorStore.applicationStore.notifyError(error);
123
+ } finally {
124
+ node.isLoading = false;
125
+ }
126
+ }
127
+ }
128
+
129
+ *refreshTreeData(): GeneratorFn<void> {
130
+ const openingNodeIds = new Set(
131
+ Array.from(this.getTreeData().nodes.values())
132
+ .filter((node) => node.isOpen)
133
+ .map((node) => node.id),
134
+ );
135
+ const selectedNodeId = this.selectedNode?.id;
136
+ this.refreshDataState.inProgress();
137
+ try {
138
+ this.treeData = this.buildTreeData((yield this.getRootNodes()) as V[]);
139
+ } catch (error) {
140
+ assertErrorThrown(error);
141
+ this.editorStore.applicationStore.notifyError(error);
142
+ this.refreshDataState.fail();
143
+ return;
144
+ }
145
+ const nodesToOpen = this.getTreeData()
146
+ .rootIds.map((id) =>
147
+ guaranteeNonNullable(this.getTreeData().nodes.get(id)),
148
+ )
149
+ .filter((node) => openingNodeIds.has(node.id));
150
+ yield this.refreshOpenNodes(nodesToOpen, openingNodeIds);
151
+ if (selectedNodeId && this.getTreeData().nodes.has(selectedNodeId)) {
152
+ this.setSelectedNode(
153
+ guaranteeNonNullable(this.getTreeData().nodes.get(selectedNodeId)),
154
+ );
155
+ }
156
+ }
157
+
158
+ async refreshOpenNodes(
159
+ nodesToOpen: T[],
160
+ openingNodeIds: Set<string>,
161
+ ): Promise<void> {
162
+ await Promise.all(
163
+ nodesToOpen.map((node) => {
164
+ openingNodeIds.delete(node.id);
165
+ return flowResult(this.expandNode(node)).catch(() => undefined);
166
+ }),
167
+ );
168
+ nodesToOpen = nodesToOpen
169
+ .flatMap((node) => node.childrenIds ?? [])
170
+ .map((childId) =>
171
+ guaranteeNonNullable(this.getTreeData().nodes.get(childId)),
172
+ )
173
+ .filter((node) => openingNodeIds.has(node.id));
174
+ if (nodesToOpen.length) {
175
+ return this.refreshOpenNodes(nodesToOpen, openingNodeIds);
176
+ }
177
+ return Promise.resolve();
178
+ }
179
+ }