Skip to content

Commit 58a1794

Browse files
committed
feat(Configuration): add support for ember test run configuration
1 parent b1e11db commit 58a1794

14 files changed

+580
-1
lines changed

doc/features.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,14 @@ A new `Ember Serve` run configuration can be created through
144144
To configure advanced settings like the server host, proxy or ssl, expand the
145145
`Advanced settings` panel.
146146

147+
### Running ember tests
148+
149+
This plugin also adds a `Ember Test` run configuration that will run your projects tests.
150+
A new `Ember Test` run configuration can be created through
151+
`Run → Edit Configurations...`.
152+
153+
To configure advanced settings like the server host, test filter or config file, expand the
154+
`Advanced settings` panel.
147155

148156
Live Templates
149157
-------------------------------------------------------------------------------

src/main/kotlin/com/emberjs/configuration/EmberCommandLineState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import com.intellij.execution.process.ProcessHandler
77
import com.intellij.execution.process.ProcessTerminatedListener
88
import com.intellij.execution.runners.ExecutionEnvironment
99

10-
class EmberCommandLineState(environment: ExecutionEnvironment) : CommandLineState(environment) {
10+
open class EmberCommandLineState(environment: ExecutionEnvironment) : CommandLineState(environment) {
1111
override fun startProcess(): ProcessHandler {
1212
val configuration = (environment.runProfile as EmberConfiguration)
1313
val argList = configuration.options.toCommandLineOptions()
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.emberjs.configuration.test
2+
3+
import com.emberjs.configuration.EmberCommandLineState
4+
import com.emberjs.configuration.EmberConfiguration
5+
import com.intellij.execution.DefaultExecutionResult
6+
import com.intellij.execution.ExecutionResult
7+
import com.intellij.execution.Executor
8+
import com.intellij.execution.configurations.RunConfiguration
9+
import com.intellij.execution.process.ProcessHandler
10+
import com.intellij.execution.runners.ExecutionEnvironment
11+
import com.intellij.execution.runners.ProgramRunner
12+
import com.intellij.execution.testframework.sm.SMTestRunnerConnectionUtil
13+
import com.intellij.execution.testframework.autotest.ToggleAutoTestAction
14+
import com.intellij.execution.testframework.sm.SMTestRunnerConnectionUtil.createAndAttachConsole
15+
16+
class EmberTestCommandLineState(environment: ExecutionEnvironment) : EmberCommandLineState(environment) {
17+
private val TEST_FRAMEWORK_NAME = "ember-qunit"
18+
19+
override fun execute(executor: Executor, runner: ProgramRunner<*>): ExecutionResult {
20+
val configuration = (environment.runProfile as EmberConfiguration)
21+
22+
// enforce teamcity reporter because converter requires it
23+
(configuration.options as EmberTestOptions).reporter.value = "teamcity"
24+
25+
val processHandler: ProcessHandler = startProcess()
26+
27+
val properties = EmberTestConsoleProperties(configuration as RunConfiguration, TEST_FRAMEWORK_NAME, executor)
28+
val console = createAndAttachConsole(TEST_FRAMEWORK_NAME, processHandler, properties)
29+
30+
SMTestRunnerConnectionUtil.createAndAttachConsole(TEST_FRAMEWORK_NAME, processHandler, properties)
31+
32+
val executionResult = DefaultExecutionResult(console, processHandler, *createActions(console, processHandler))
33+
executionResult.setRestartActions(ToggleAutoTestAction())
34+
return executionResult
35+
}
36+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.emberjs.configuration.test
2+
3+
import com.emberjs.configuration.EmberConfiguration
4+
import com.emberjs.configuration.test.ui.EmberTestSettingsEditor
5+
import com.intellij.execution.ExecutionException
6+
import com.intellij.execution.Executor
7+
import com.intellij.execution.configurations.*
8+
import com.intellij.execution.runners.ExecutionEnvironment
9+
import com.intellij.openapi.options.SettingsEditor
10+
import com.intellij.openapi.project.Project
11+
import org.jdom.Element
12+
import org.jetbrains.annotations.NotNull
13+
import org.jetbrains.annotations.Nullable
14+
15+
class EmberTestConfiguration(project: Project, factory: ConfigurationFactory, name: String) : RunConfigurationBase(project, factory, name), EmberConfiguration {
16+
override val options = EmberTestOptions()
17+
override val command: String = "test"
18+
19+
@NotNull
20+
override fun getConfigurationEditor(): SettingsEditor<out RunConfiguration> {
21+
return EmberTestSettingsEditor()
22+
}
23+
24+
@Throws(RuntimeConfigurationException::class)
25+
override fun checkConfiguration() {
26+
27+
}
28+
29+
@Nullable
30+
@Throws(ExecutionException::class)
31+
override fun getState(@NotNull executor: Executor, @NotNull executionEnvironment: ExecutionEnvironment): RunProfileState? {
32+
return EmberTestCommandLineState(executionEnvironment)
33+
}
34+
35+
override fun writeExternal(element: Element?) {
36+
super.writeExternal(element)
37+
element?.let {
38+
options.fields().forEach { optionsField -> optionsField.writeToElement(element)}
39+
}
40+
}
41+
42+
override fun readExternal(element: Element?) {
43+
super.readExternal(element)
44+
element?.let {
45+
options.fields().forEach { optionsField -> optionsField.readFromElement(element) }
46+
}
47+
}
48+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.emberjs.configuration.test
2+
3+
import com.intellij.execution.configurations.ConfigurationFactory
4+
import com.intellij.execution.configurations.ConfigurationType
5+
import com.intellij.execution.configurations.RunConfiguration
6+
import com.intellij.openapi.project.Project
7+
8+
class EmberTestConfigurationFactory(type: ConfigurationType) : ConfigurationFactory(type) {
9+
10+
override fun createTemplateConfiguration(project: Project): RunConfiguration {
11+
return EmberTestConfiguration(project, this, "Ember test")
12+
}
13+
14+
override fun getName(): String {
15+
return FACTORY_NAME;
16+
}
17+
18+
companion object {
19+
private val FACTORY_NAME = "Ember test configuration factory"
20+
}
21+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.emberjs.configuration.test
2+
3+
import com.emberjs.icons.EmberIcons
4+
import com.intellij.execution.configurations.ConfigurationFactory
5+
import com.intellij.execution.configurations.ConfigurationTypeBase
6+
7+
class EmberTestConfigurationType : ConfigurationTypeBase(
8+
"EMBER_TEST_CONFIGURATION",
9+
"Ember Test",
10+
"Ember Test Configuration",
11+
EmberIcons.ICON_16
12+
) {
13+
override fun getConfigurationFactories(): Array<ConfigurationFactory> {
14+
return arrayOf(EmberTestConfigurationFactory(this))
15+
}
16+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.emberjs.configuration.test
2+
3+
import com.intellij.execution.Executor
4+
import com.intellij.execution.configurations.RunConfiguration
5+
import com.intellij.execution.testframework.TestConsoleProperties
6+
import com.intellij.execution.testframework.sm.SMCustomMessagesParsing
7+
import com.intellij.execution.testframework.sm.runner.OutputToGeneralTestEventsConverter
8+
import com.intellij.execution.testframework.sm.runner.SMTRunnerConsoleProperties
9+
10+
class EmberTestConsoleProperties(
11+
configuration: RunConfiguration,
12+
TEST_FRAMEWORK_NAME: String,
13+
executor: Executor) : SMTRunnerConsoleProperties(
14+
configuration,
15+
TEST_FRAMEWORK_NAME,
16+
executor
17+
), SMCustomMessagesParsing {
18+
override fun createTestEventsConverter(testFrameworkName: String, consoleProperties: TestConsoleProperties): OutputToGeneralTestEventsConverter {
19+
return EmberTestOutputToGeneralTestEventsConverter(testFrameworkName, consoleProperties);
20+
}
21+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.emberjs.configuration.test
2+
3+
import com.emberjs.configuration.EmberOptions
4+
import com.emberjs.configuration.OptionsField
5+
import com.emberjs.configuration.StringOptionsField
6+
7+
class EmberTestOptions : EmberOptions {
8+
val environment = StringOptionsField("development", "ENVIRONMENT", "environment")
9+
val configFile = StringOptionsField("", "CONFIG_FILE", "config-file")
10+
val host = StringOptionsField("", "HOST", "host")
11+
val testPort = StringOptionsField("7357", "TEST_PORT", "test-port")
12+
val filter = StringOptionsField("", "FILTER", "filter")
13+
val module = StringOptionsField("", "MODULE", "module")
14+
val watcher = StringOptionsField("events", "WATCHER", "watcher")
15+
val testemDebug = StringOptionsField("", "TESTEM_DEBUG", "testem-debug")
16+
val testPage = StringOptionsField("", "TEST_PAGE", "test-page")
17+
val path = StringOptionsField("", "PATH", "path")
18+
val query = StringOptionsField("", "QUERY", "query")
19+
val reporter = StringOptionsField("tap", "REPORTER", "reporter")
20+
21+
override fun fields(): Array<OptionsField<out Any>> {
22+
return arrayOf(
23+
environment,
24+
configFile,
25+
host,
26+
testPort,
27+
filter,
28+
module,
29+
watcher,
30+
testemDebug,
31+
testPage,
32+
path,
33+
query,
34+
reporter
35+
)
36+
}
37+
38+
override fun toCommandLineOptions(): Array<String> {
39+
return fields()
40+
.filter { optionsField ->
41+
optionsField.value != optionsField.default &&
42+
optionsField.value.toString().isNotEmpty()
43+
}
44+
.map { optionsField -> "--${optionsField.cmdlineOptionName}=${optionsField.value}" }
45+
.toTypedArray()
46+
}
47+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.emberjs.configuration.test
2+
3+
import com.intellij.execution.process.ProcessOutputTypes
4+
import com.intellij.execution.testframework.TestConsoleProperties
5+
import com.intellij.execution.testframework.sm.runner.OutputLineSplitter
6+
import com.intellij.execution.testframework.sm.runner.OutputToGeneralTestEventsConverter
7+
import com.intellij.openapi.util.Key
8+
9+
class EmberTestOutputToGeneralTestEventsConverter(testFrameworkName: String, consoleProperties: TestConsoleProperties) :
10+
OutputToGeneralTestEventsConverter(testFrameworkName, consoleProperties) {
11+
var splitter: OutputLineSplitter;
12+
13+
private val REGEX_TEAMCITY_LINE = """^##teamcity.*""".toRegex(RegexOption.DOT_MATCHES_ALL)
14+
15+
init {
16+
splitter = object : OutputLineSplitter(true) {
17+
override fun onLineAvailable(text: String, outputType: Key<*>, tcLikeFakeOutput: Boolean) {
18+
subProcessConsistentText(text, outputType, tcLikeFakeOutput);
19+
}
20+
}
21+
}
22+
23+
fun subProcessConsistentText(text: String, outputType: Key<*>, tcLikeFakeOutput: Boolean) {
24+
if (REGEX_TEAMCITY_LINE.matches(text)) {
25+
super.processConsistentText(text, ProcessOutputTypes.STDOUT, false)
26+
}
27+
}
28+
29+
override fun process(text: String?, outputType: Key<*>?) {
30+
splitter.process(text, outputType);
31+
}
32+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.emberjs.configuration.test
2+
3+
import com.intellij.execution.configurations.RunProfile
4+
import com.intellij.execution.executors.DefaultRunExecutor
5+
import com.intellij.execution.runners.DefaultProgramRunner
6+
7+
class EmberTestProgramRunner : DefaultProgramRunner() {
8+
override fun getRunnerId(): String = "EmberTestRunner"
9+
10+
override fun canRun(executorId: String, profile: RunProfile): Boolean =
11+
executorId == DefaultRunExecutor.EXECUTOR_ID && profile is EmberTestConfiguration
12+
}

0 commit comments

Comments
 (0)