IDEA-250342 [new run config UI] Add a way to edit run configuration from the run...
[idea/community.git] / java / compiler / tests / com / intellij / compiler / artifacts / DynamicArtifactExtensionsLoaderTest.kt
1 // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package com.intellij.compiler.artifacts
3
4 import com.intellij.openapi.Disposable
5 import com.intellij.openapi.application.runWriteAction
6 import com.intellij.openapi.extensions.ExtensionPointName
7 import com.intellij.openapi.module.impl.ProjectLoadingErrorsHeadlessNotifier
8 import com.intellij.openapi.project.Project
9 import com.intellij.openapi.util.Disposer
10 import com.intellij.packaging.artifacts.*
11 import com.intellij.packaging.elements.*
12 import com.intellij.packaging.impl.artifacts.InvalidArtifactType
13 import com.intellij.packaging.impl.artifacts.PlainArtifactType
14 import com.intellij.packaging.ui.ArtifactEditorContext
15 import com.intellij.packaging.ui.ArtifactPropertiesEditor
16 import com.intellij.packaging.ui.PackagingElementPresentation
17 import com.intellij.testFramework.HeavyPlatformTestCase
18 import com.intellij.util.ui.EmptyIcon
19 import java.util.function.Consumer
20 import javax.swing.Icon
21
22 class DynamicArtifactExtensionsLoaderTest : HeavyPlatformTestCase() {
23   fun `test unload and load artifact type`() {
24     ProjectLoadingErrorsHeadlessNotifier.setErrorHandler(Consumer {}, testRootDisposable)
25     val artifactManager = ArtifactManager.getInstance(myProject)
26     runWithRegisteredExtension(MockArtifactType(), ArtifactType.EP_NAME) {
27       artifactManager.addArtifact("mock", MockArtifactType.getInstance(), PackagingElementFactory.getInstance().createArtifactRootElement())
28     }
29
30     val invalid = assertOneElement(artifactManager.allArtifactsIncludingInvalid)
31     assertEquals(InvalidArtifactType.getInstance(), invalid.artifactType)
32     assertEquals("mock", invalid.name)
33     registerExtension(MockArtifactType(), ArtifactType.EP_NAME, testRootDisposable)
34     assertOneElement(artifactManager.allArtifactsIncludingInvalid)
35     val artifact = assertOneElement(artifactManager.getArtifactsByType(MockArtifactType.getInstance()))
36     assertEquals("mock", artifact.name)
37   }
38
39   fun `test unload and load packaging element type`() {
40     val artifactManager = ArtifactManager.getInstance(myProject)
41     runWithRegisteredExtension(MockPackagingElementType(), PackagingElementType.EP_NAME) {
42       val root = PackagingElementFactory.getInstance().createArtifactRootElement()
43       root.addFirstChild(MockPackagingElement().apply { this.state.data = "data" })
44       artifactManager.addArtifact("mock", PlainArtifactType.getInstance(), root)
45     }
46
47     val invalid = assertOneElement(artifactManager.allArtifactsIncludingInvalid)
48     assertEquals(InvalidArtifactType.getInstance(), invalid.artifactType)
49     assertEquals("mock", invalid.name)
50
51     registerExtension(MockPackagingElementType(), PackagingElementType.EP_NAME, testRootDisposable)
52     assertOneElement(artifactManager.allArtifactsIncludingInvalid)
53     val artifact = assertOneElement(artifactManager.getArtifactsByType(PlainArtifactType.getInstance()))
54     assertEquals("mock", artifact.name)
55     assertEquals("data", (artifact.rootElement.children.single() as MockPackagingElement).state.data)
56   }
57
58   fun `test unload and load artifact properties`() {
59     val artifactManager = ArtifactManager.getInstance(myProject)
60     runWithRegisteredExtension(MockArtifactPropertiesProvider(), ArtifactPropertiesProvider.EP_NAME) {
61       val model = artifactManager.createModifiableModel()
62       val artifact = model.addArtifact("mock", PlainArtifactType.getInstance())
63       artifact.setProperties(MockArtifactPropertiesProvider.getInstance(), MockArtifactProperties().apply { data = "data" })
64       runWriteAction { model.commit() }
65     }
66
67     val invalid = assertOneElement(artifactManager.allArtifactsIncludingInvalid)
68     assertEquals(InvalidArtifactType.getInstance(), invalid.artifactType)
69     assertEquals("mock", invalid.name)
70
71     registerExtension(MockArtifactPropertiesProvider(), ArtifactPropertiesProvider.EP_NAME, testRootDisposable)
72     assertOneElement(artifactManager.allArtifactsIncludingInvalid)
73     val artifact = assertOneElement(artifactManager.getArtifactsByType(PlainArtifactType.getInstance()))
74     assertEquals("mock", artifact.name)
75     assertEquals("data", (artifact.getProperties(MockArtifactPropertiesProvider.getInstance()) as MockArtifactProperties).data)
76   }
77
78   private inline fun <T> runWithRegisteredExtension(extension: T, extensionPoint: ExtensionPointName<T>, action: () -> Unit) {
79     val disposable = Disposer.newDisposable()
80     registerExtension(extension, extensionPoint, disposable)
81     try {
82       action()
83     }
84     finally {
85       Disposer.dispose(disposable)
86     }
87   }
88
89   private fun <T> registerExtension(type: T, extensionPointName: ExtensionPointName<T>, disposable: Disposable) {
90     val artifactTypeDisposable = Disposer.newDisposable()
91     Disposer.register(disposable, Disposable {
92       runWriteAction {
93         Disposer.dispose(artifactTypeDisposable)
94       }
95     })
96     extensionPointName.point.registerExtension(type, artifactTypeDisposable)
97   }
98
99   override fun setUp() {
100     super.setUp()
101     ProjectLoadingErrorsHeadlessNotifier.setErrorHandler(Consumer {}, testRootDisposable)
102   }
103 }
104
105 private class MockArtifactType : ArtifactType("mock", "Mock") {
106   companion object {
107     fun getInstance() = EP_NAME.findExtension(MockArtifactType::class.java)!!
108   }
109
110   override fun getIcon(): Icon = EmptyIcon.ICON_16
111
112   override fun getDefaultPathFor(kind: PackagingElementOutputKind): String? = ""
113
114   override fun createRootElement(artifactName: String): CompositePackagingElement<*> {
115     return PackagingElementFactory.getInstance().createArtifactRootElement()
116   }
117 }
118
119 private class MockPackagingElement : PackagingElement<MockPackagingElementState>(PackagingElementType.EP_NAME.findExtensionOrFail(MockPackagingElementType::class.java)) {
120   private val state: MockPackagingElementState = MockPackagingElementState("")
121
122   override fun getState(): MockPackagingElementState = state
123
124   override fun loadState(state: MockPackagingElementState) {
125     this.state.data = state.data
126   }
127
128   override fun isEqualTo(element: PackagingElement<*>): Boolean = (element as? MockPackagingElement)?.state?.data == state.data
129
130   override fun createPresentation(context: ArtifactEditorContext): PackagingElementPresentation {
131     throw UnsupportedOperationException()
132   }
133 }
134
135 private class MockPackagingElementState(var data: String = "")
136
137 private class MockPackagingElementType : PackagingElementType<MockPackagingElement>("mock-element", "Mock Element") {
138   override fun canCreate(context: ArtifactEditorContext, artifact: Artifact): Boolean = true
139
140   override fun chooseAndCreate(context: ArtifactEditorContext,
141                                artifact: Artifact,
142                                parent: CompositePackagingElement<*>): MutableList<out PackagingElement<*>> {
143     throw UnsupportedOperationException()
144   }
145
146   override fun createEmpty(project: Project): MockPackagingElement {
147     return MockPackagingElement()
148   }
149 }
150
151 private class MockArtifactProperties : ArtifactProperties<MockArtifactProperties>() {
152   var data: String = ""
153
154   override fun getState(): MockArtifactProperties? {
155     return this
156   }
157
158   override fun loadState(state: MockArtifactProperties) {
159     data = state.data
160   }
161
162   override fun createEditor(context: ArtifactEditorContext): ArtifactPropertiesEditor {
163     throw UnsupportedOperationException()
164   }
165 }
166
167 private class MockArtifactPropertiesProvider : ArtifactPropertiesProvider("mock-properties") {
168   companion object {
169     fun getInstance(): MockArtifactPropertiesProvider = EP_NAME.findExtensionOrFail(MockArtifactPropertiesProvider::class.java)
170   }
171
172   override fun createProperties(artifactType: ArtifactType): ArtifactProperties<*> = MockArtifactProperties()
173 }