@@ -23,16 +23,15 @@ import org.jetbrains.kotlin.idea.util.application.invokeLater
23
23
import org.jetbrains.kotlin.idea.util.application.runReadAction
24
24
import org.jetbrains.kotlin.idea.util.application.runWriteAction
25
25
import org.jetbrains.kotlin.konan.file.File
26
+ import org.utbot.framework.plugin.api.TimeoutException
26
27
import org.utbot.intellij.plugin.ui.utils.showErrorDialogLater
27
28
import org.utbot.intellij.plugin.ui.utils.testModules
28
29
import settings.JsDynamicSettings
29
30
import settings.JsExportsSettings.endComment
30
31
import settings.JsExportsSettings.startComment
31
- import settings.JsPackagesSettings.mochaData
32
- import settings.JsPackagesSettings.nycData
33
- import settings.JsPackagesSettings.ternData
34
32
import settings.JsTestGenerationSettings.dummyClassName
35
- import settings.PackageData
33
+ import settings.PackageDataService
34
+ import settings.jsPackagesList
36
35
import utils.JsCmdExec
37
36
import utils.OsProvider
38
37
import java.io.IOException
@@ -58,9 +57,10 @@ object JsDialogProcessor {
58
57
) {
59
58
override fun run (indicator : ProgressIndicator ) {
60
59
invokeLater {
61
- checkAndInstallRequirement(model.project, model.pathToNPM, mochaData)
62
- checkAndInstallRequirement(model.project, model.pathToNPM, nycData)
63
- checkAndInstallRequirement(model.project, model.pathToNPM, ternData)
60
+ if (! PackageDataService (
61
+ model.containingFilePath, model.project.basePath!! , model.pathToNPM
62
+ ).checkAndInstallRequirements(project)
63
+ ) return @invokeLater
64
64
createDialog(model)?.let { dialogWindow ->
65
65
if (! dialogWindow.showAndGet()) return @invokeLater
66
66
// Since Tern.js accesses containing file, sync with file system required before test generation.
@@ -76,36 +76,31 @@ object JsDialogProcessor {
76
76
}).queue()
77
77
}
78
78
79
- private fun findNodeAndNPM (): Pair <String , String >? =
80
- try {
81
- val pathToNode = NodeJsLocalInterpreterManager .getInstance()
82
- .interpreters.first().interpreterSystemIndependentPath
83
- val (_, errorText) = JsCmdExec .runCommand(
84
- shouldWait = true ,
85
- cmd = arrayOf(" \" ${pathToNode} \" " , " -v" )
86
- )
87
- if (errorText.isNotEmpty()) throw NoSuchElementException ()
88
- val pathToNPM =
89
- pathToNode.substringBeforeLast(" /" ) + " /" + " npm" + OsProvider .getProviderByOs().npmPackagePostfix
90
- pathToNode to pathToNPM
91
- } catch (e: NoSuchElementException ) {
92
- Messages .showErrorDialog(
93
- " Node.js interpreter is not found in IDEA settings.\n " +
94
- " Please set it in Settings > Languages & Frameworks > Node.js" ,
95
- " Requirement Error"
96
- )
97
- logger.error { " Node.js interpreter was not found in IDEA settings." }
98
- null
99
- } catch (e: IOException ) {
100
- Messages .showErrorDialog(
101
- " Node.js interpreter path is corrupted in IDEA settings.\n " +
102
- " Please check Settings > Languages & Frameworks > Node.js" ,
103
- " Requirement Error"
104
- )
105
- logger.error { " Node.js interpreter path is corrupted in IDEA settings." }
106
- null
107
- }
108
-
79
+ private fun findNodeAndNPM (): Pair <String , String >? = try {
80
+ val pathToNode =
81
+ NodeJsLocalInterpreterManager .getInstance().interpreters.first().interpreterSystemIndependentPath
82
+ val (_, errorText) = JsCmdExec .runCommand(
83
+ shouldWait = true , 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 " + " Please set it in Settings > Languages & Frameworks > Node.js" ,
92
+ " Requirement Error"
93
+ )
94
+ logger.error { " Node.js interpreter was not found in IDEA settings." }
95
+ null
96
+ } catch (e: IOException ) {
97
+ Messages .showErrorDialog(
98
+ " Node.js interpreter path is corrupted in IDEA settings.\n " + " Please check Settings > Languages & Frameworks > Node.js" ,
99
+ " Requirement Error"
100
+ )
101
+ logger.error { " Node.js interpreter path is corrupted in IDEA settings." }
102
+ null
103
+ }
109
104
110
105
private fun createJsTestModel (
111
106
project : Project ,
@@ -138,7 +133,6 @@ object JsDialogProcessor {
138
133
this .pathToNode = pathToNode
139
134
this .pathToNPM = pathToNPM
140
135
}
141
-
142
136
}
143
137
144
138
private fun createDialog (jsTestsModel : JsTestsModel ? ) = jsTestsModel?.let { JsDialogWindow (it) }
@@ -159,10 +153,8 @@ object JsDialogProcessor {
159
153
val testDir = PsiDirectoryFactory .getInstance(project).createDirectory(
160
154
model.testSourceRoot!!
161
155
)
162
- val testFileName = normalizedContainingFilePath.substringAfterLast(" /" )
163
- .replace(Regex (" .js" ), " Test.js" )
164
- val testGenerator = JsTestGenerator (
165
- fileText = editor.document.text,
156
+ val testFileName = normalizedContainingFilePath.substringAfterLast(" /" ).replace(Regex (" .js" ), " Test.js" )
157
+ val testGenerator = JsTestGenerator (fileText = editor.document.text,
166
158
sourceFilePath = normalizedContainingFilePath,
167
159
projectPath = model.project.basePath?.replace(File .separator, " /" )
168
160
? : throw IllegalStateException (" Can't access project path." ),
@@ -267,45 +259,47 @@ object JsDialogProcessor {
267
259
}
268
260
}
269
261
270
- fun checkAndInstallRequirement (
271
- project : Project ,
272
- pathToNPM : String ,
273
- requirement : PackageData ,
274
- ) {
275
- if (! requirement.findPackageByNpm(project.basePath!! , pathToNPM)) {
276
- installMissingRequirement(project, pathToNPM, requirement)
277
- }
278
- }
279
-
280
- private fun installMissingRequirement (
281
- project : Project ,
282
- pathToNPM : String ,
283
- requirement : PackageData ,
284
- ) {
262
+ private fun PackageDataService.checkAndInstallRequirements (project : Project ): Boolean {
263
+ val missingPackages = jsPackagesList.filterNot { this .findPackage(it) }
264
+ if (missingPackages.isEmpty()) return true
285
265
val message = """
286
- Requirement is not installed:
287
- ${requirement. packageName}
288
- Install it ?
266
+ Requirements are not installed:
267
+ ${missingPackages.joinToString { it. packageName } }
268
+ Install them ?
289
269
""" .trimIndent()
290
270
val result = Messages .showOkCancelDialog(
291
- project,
292
- message,
293
- " Requirement Missmatch Error" ,
294
- " Install" ,
295
- " Cancel" ,
296
- null
271
+ project, message, " Requirements Missmatch Error" , " Install" , " Cancel" , null
297
272
)
298
273
299
274
if (result == Messages .CANCEL )
300
- return
275
+ return false
301
276
302
- val (_, errorText) = requirement.installPackage(project.basePath!! , pathToNPM)
303
-
304
- if (errorText.isNotEmpty()) {
277
+ try {
278
+ val (_, errorText) = this .installMissingPackages(missingPackages)
279
+ if (errorText.isNotEmpty()) {
280
+ showErrorDialogLater(
281
+ project,
282
+ " Requirements installing failed with some reason:\n ${errorText} " ,
283
+ " Failed to install requirements"
284
+ )
285
+ return false
286
+ }
287
+ return true
288
+ } catch (_: TimeoutException ) {
305
289
showErrorDialogLater(
306
290
project,
307
- " Requirements installing failed with some reason:\n ${errorText} " ,
308
- " Requirements error"
291
+ """
292
+ Requirements installing failed due to the exceeded waiting time for the installation, check your internet connection.
293
+
294
+ Try to install missing npm packages manually:
295
+ ${
296
+ missingPackages.joinToString(separator = " \n " ) {
297
+ " > npm install ${it.npmListFlag} ${it.packageName} "
298
+ }
299
+ }
300
+ """ .trimIndent(),
301
+ " Failed to install requirements"
309
302
)
303
+ return false
310
304
}
311
305
}
0 commit comments