@@ -18,7 +18,6 @@ import com.intellij.psi.PsiDocumentManager
18
18
import com.intellij.psi.PsiFileFactory
19
19
import com.intellij.psi.impl.file.PsiDirectoryFactory
20
20
import com.intellij.util.concurrency.AppExecutorUtil
21
- import framework.codegen.Mocha
22
21
import mu.KotlinLogging
23
22
import org.jetbrains.kotlin.idea.util.application.invokeLater
24
23
import org.jetbrains.kotlin.idea.util.application.runReadAction
@@ -29,8 +28,12 @@ import org.utbot.intellij.plugin.ui.utils.testModules
29
28
import settings.JsDynamicSettings
30
29
import settings.JsExportsSettings.endComment
31
30
import settings.JsExportsSettings.startComment
31
+ import settings.JsPackagesSettings.mochaData
32
32
import settings.JsTestGenerationSettings.dummyClassName
33
+ import settings.PackageData
33
34
import utils.JsCmdExec
35
+ import utils.OsProvider
36
+ import java.io.IOException
34
37
35
38
private val logger = KotlinLogging .logger {}
36
39
@@ -45,14 +48,17 @@ object JsDialogProcessor {
45
48
editor : Editor ,
46
49
file : JSFile
47
50
) {
48
- val model = createJsTestModel(project, srcModule, fileMethods, focusedMethod, containingFilePath, file)
51
+ val model =
52
+ createJsTestModel(project, srcModule, fileMethods, focusedMethod, containingFilePath, file) ? : return
49
53
(object : Task .Backgroundable (
50
54
project,
51
55
" Check the requirements"
52
56
) {
53
57
override fun run (indicator : ProgressIndicator ) {
54
58
invokeLater {
55
- getFrameworkLibraryPath(Mocha .displayName.lowercase(), model)
59
+ if (! mochaData.findPackageByNpm(model.project.basePath!! , model.pathToNPM)) {
60
+ installMissingRequirement(model.project, model.pathToNPM, mochaData)
61
+ }
56
62
createDialog(model)?.let { dialogProcessor ->
57
63
if (! dialogProcessor.showAndGet()) return @invokeLater
58
64
// Since Tern.js accesses containing file, sync with file system required before test generation.
@@ -68,6 +74,37 @@ object JsDialogProcessor {
68
74
}).queue()
69
75
}
70
76
77
+ private fun findNodeAndNPM (): Pair <String , String >? =
78
+ try {
79
+ val pathToNode = NodeJsLocalInterpreterManager .getInstance()
80
+ .interpreters.first().interpreterSystemIndependentPath
81
+ val (_, errorText) = JsCmdExec .runCommand(
82
+ shouldWait = true ,
83
+ cmd = arrayOf(" \" ${pathToNode} \" " , " -v" )
84
+ )
85
+ if (errorText.isNotEmpty()) throw NoSuchElementException ()
86
+ val pathToNPM =
87
+ pathToNode.substringBeforeLast(" /" ) + " /" + " npm" + OsProvider .getProviderByOs().npmPackagePostfix
88
+ pathToNode to pathToNPM
89
+ } catch (e: NoSuchElementException ) {
90
+ Messages .showErrorDialog(
91
+ " Node.js interpreter is not found in IDEA settings.\n " +
92
+ " Please set it in Settings > Languages & Frameworks > Node.js" ,
93
+ " Requirement Error"
94
+ )
95
+ logger.error { " Node.js interpreter was not found in IDEA settings." }
96
+ null
97
+ } catch (e: IOException ) {
98
+ Messages .showErrorDialog(
99
+ " Node.js interpreter path is corrupted in IDEA settings.\n " +
100
+ " Please check Settings > Languages & Frameworks > Node.js" ,
101
+ " Requirement Error"
102
+ )
103
+ logger.error { " Node.js interpreter path is corrupted in IDEA settings." }
104
+ null
105
+ }
106
+
107
+
71
108
private fun createJsTestModel (
72
109
project : Project ,
73
110
srcModule : Module ,
@@ -86,43 +123,22 @@ object JsDialogProcessor {
86
123
showErrorDialogLater(project, errorMessage, " Test source roots not found" )
87
124
return null
88
125
}
126
+ val (pathToNode, pathToNPM) = findNodeAndNPM() ? : return null
89
127
return JsTestsModel (
90
128
project = project,
91
129
srcModule = srcModule,
92
130
potentialTestModules = testModules,
93
131
fileMethods = fileMethods,
94
132
selectedMethods = if (focusedMethod != null ) setOf (focusedMethod) else emptySet(),
95
- file = file
133
+ file = file,
96
134
).apply {
97
135
containingFilePath = filePath
136
+ this .pathToNode = pathToNode
137
+ this .pathToNPM = pathToNPM
98
138
}
99
-
100
139
}
101
140
102
- private fun createDialog (
103
- jsTestsModel : JsTestsModel ?
104
- ): JsDialogWindow ? {
105
- try {
106
- jsTestsModel?.pathToNode = NodeJsLocalInterpreterManager .getInstance()
107
- .interpreters.first().interpreterSystemIndependentPath
108
- val (_, errorText) = JsCmdExec .runCommand(
109
- shouldWait = true ,
110
- cmd = arrayOf(" node" , " -v" )
111
- )
112
- if (errorText.isNotEmpty()) throw NoSuchElementException ()
113
- } catch (e: NoSuchElementException ) {
114
- Messages .showErrorDialog(
115
- " Node.js interpreter is not found in IDEA settings.\n " +
116
- " Please set it in Settings > Languages & Frameworks > Node.js" ,
117
- " Requirement Error"
118
- )
119
- logger.error { " Node.js interpreter was not found in IDEA settings." }
120
- return null
121
- }
122
- return jsTestsModel?.let {
123
- JsDialogWindow (it)
124
- }
125
- }
141
+ private fun createDialog (jsTestsModel : JsTestsModel ? ) = jsTestsModel?.let { JsDialogWindow (it) }
126
142
127
143
private fun unblockDocument (project : Project , document : Document ) {
128
144
PsiDocumentManager .getInstance(project).apply {
@@ -248,10 +264,10 @@ object JsDialogProcessor {
248
264
}
249
265
250
266
// TODO(MINOR): Add indicator.text for each installation
251
- fun installMissingRequirement (project : Project , pathToNPM : String , requirement : String ) {
267
+ fun installMissingRequirement (project : Project , pathToNPM : String , requirement : PackageData ) {
252
268
val message = """
253
269
Requirement is not installed:
254
- $requirement
270
+ ${ requirement.packageName}
255
271
Install it?
256
272
""" .trimIndent()
257
273
val result = Messages .showOkCancelDialog(
@@ -266,7 +282,7 @@ fun installMissingRequirement(project: Project, pathToNPM: String, requirement:
266
282
if (result == Messages .CANCEL )
267
283
return
268
284
269
- val (_, errorText) = installRequirement(pathToNPM, requirement, project.basePath)
285
+ val (_, errorText) = requirement.installPackage( project.basePath!! , pathToNPM )
270
286
271
287
if (errorText.isNotEmpty()) {
272
288
showErrorDialogLater(
0 commit comments