15 | }
16 |
17 | fun Function1
.disposable(): Function1
{
18 | if (this is DisposableFunction1) {
19 | return this
20 | }
21 | return DisposableFunction1(this)
22 | }
23 |
24 | class DisposableFunction0(val function: Function0) : Function0 {
25 | private var todo = AtomicBoolean(true)
26 |
27 | override fun invoke(): T? {
28 | if (todo.compareAndSet(true, false)) {
29 | return function()
30 | }
31 | return null
32 | }
33 | }
34 |
35 | class DisposableFunction1(val function: Function1
) : Function1
{
36 | private var todo = AtomicBoolean(true)
37 |
38 | override fun invoke(p1: P): R? {
39 | if (todo.compareAndSet(true, false)) {
40 | return function(p1)
41 | }
42 | return null
43 | }
44 | }
--------------------------------------------------------------------------------
/idea-plugin/src/main/kotlin/com/itangcent/utils/Emojis.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.utils
2 |
3 | object Emojis {
4 |
5 | const val BUST = "\uD83D\uDC64"
6 |
7 | const val BUSTS = "\uD83D\uDC65"
8 | }
--------------------------------------------------------------------------------
/idea-plugin/src/main/kotlin/com/itangcent/utils/EnumKit.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.utils
2 |
3 | object EnumKit {
4 | /**
5 | * Safely converts a string to an enum constant, returning null if the name doesn't match any enum value
6 | * instead of throwing an IllegalArgumentException.
7 | *
8 | * @param name The name of the enum constant to return
9 | * @return The enum constant of the specified name, or null if not found
10 | */
11 | inline fun > safeValueOf(name: String?): T? {
12 | if (name == null) return null
13 | return try {
14 | java.lang.Enum.valueOf(T::class.java, name)
15 | } catch (_: IllegalArgumentException) {
16 | null
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/idea-plugin/src/main/kotlin/com/itangcent/utils/FileKit.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.utils
2 |
3 | import java.io.File
4 |
5 | /**
6 | * Returns a path string with `/` converted to the OS-specific separator character.
7 | * On OSes where the separator is already `/`, the original string is returned.
8 | */
9 | fun String.localPath(): String {
10 | if (File.separatorChar != '/') {
11 | return this.replace('/', File.separatorChar)
12 | }
13 | return this
14 | }
--------------------------------------------------------------------------------
/idea-plugin/src/main/kotlin/com/itangcent/utils/GiteeSupport.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.utils
2 |
3 | import java.util.regex.Pattern
4 |
5 | /**
6 | * Converts a raw GitHub URL to a Gitee raw URL.
7 | *
8 | * Raw URLs have the format:
9 | * `https://raw.githubusercontent.com/$user/$project/$file`
10 | *
11 | * This converts it to the Gitee raw URL format:
12 | * `https://gitee.com/$user/$project/raw/$file`
13 | *
14 | * @author tangcent
15 | */
16 | object GiteeSupport {
17 |
18 | private val GITHUB_RAW_URL_REGEX =
19 | Pattern.compile("https://raw.githubusercontent.com/(.*?)/(.*?)/(.*?)")
20 |
21 | /**
22 | * Converts a raw GitHub URL to a Gitee raw URL.
23 | *
24 | * https://raw.githubusercontent.com/$user/$project/$path
25 | * ->
26 | * https://gitee.com/$user/$project/raw/$path
27 | */
28 | fun convertUrlFromGithub(githubUrl: String): String? {
29 | val matcher = GITHUB_RAW_URL_REGEX.matcher(githubUrl)
30 |
31 | if (!matcher.matches()) return null
32 |
33 | val giteeUser = matcher.group(1)
34 | val giteeProject = matcher.group(2)
35 | val giteeFilePath = matcher.group(3)
36 | return "https://gitee.com/$giteeUser/$giteeProject/raw/$giteeFilePath"
37 | }
38 | }
--------------------------------------------------------------------------------
/idea-plugin/src/main/kotlin/com/itangcent/utils/Initializable.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.utils
2 |
3 | import com.itangcent.intellij.context.ActionContext
4 |
5 | /**
6 | * Interface to be implemented by beans that need to react once all their properties
7 | * have been injected by [ActionContext]: e.g. to perform custom initialization,
8 | * or merely to check that all mandatory properties have been set.
9 | */
10 | interface Initializable {
11 |
12 | fun init()
13 | }
--------------------------------------------------------------------------------
/idea-plugin/src/main/kotlin/com/itangcent/utils/NonReentrant.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.utils
2 |
3 | object NonReentrant {
4 |
5 | private val flagThreadLocal = ThreadLocal.withInitial { mutableSetOf() }
6 |
7 | fun call(flag: String, action: () -> T): T {
8 | val flags = flagThreadLocal.get()
9 | if (flags.contains(flag)) {
10 | throw NonReentrantException(flag)
11 | }
12 | flags.add(flag)
13 | try {
14 | return action()
15 | } finally {
16 | flags.remove(flag)
17 | }
18 | }
19 | }
20 |
21 | class NonReentrantException(val flag: String) : Exception("should not reentrant calls [$flag]")
--------------------------------------------------------------------------------
/idea-plugin/src/main/kotlin/com/itangcent/utils/StringKit.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.utils
2 |
3 | /**
4 | * A map of escape characters to their unescaped versions.
5 | */
6 | private val escapeCharacters = mapOf(
7 | 'b' to '\b', // Backspace
8 | 't' to '\t', // Tab
9 | 'n' to '\n', // Newline
10 | 'r' to '\r', // Carriage return
11 | '\\' to '\\', // Backslash
12 | )
13 |
14 | /**
15 | * Used to convert escaped characters in a string to their unescaped version.
16 | * For example, "\\n" would be converted to "\n".
17 | *
18 | * @return The unescaped string.
19 | */
20 | fun String.unescape(): String {
21 | val sb = StringBuilder()
22 | var escaped = false
23 | for (ch in this) {
24 | if (!escaped) {
25 | if (ch == '\\') {
26 | escaped = true
27 | } else {
28 | sb.append(ch)
29 | }
30 | continue
31 | }
32 |
33 | escaped = false
34 | if (escapeCharacters.containsKey(ch)) {
35 | sb.append(escapeCharacters[ch])
36 | continue
37 | }
38 |
39 | sb.append('\\')
40 | sb.append(ch)
41 | continue
42 | }
43 | if (escaped) {
44 | sb.append('\\')
45 | }
46 | return sb.toString()
47 | }
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/.default.built.in.easy.api.config:
--------------------------------------------------------------------------------
1 | #configs
2 | #dev=false
3 | #auto.format.url=true
4 | #max.deep=10
5 | #max.elements=512
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/.default.remote.easy.api.config:
--------------------------------------------------------------------------------
1 | !https://raw.githubusercontent.com/tangcent/easy-api/master/third/javax.validation.mock.config
2 | !https://raw.githubusercontent.com/tangcent/easy-api/master/third/swagger3.config
3 | !https://raw.githubusercontent.com/tangcent/easy-api/master/third/swagger.config
4 | !https://raw.githubusercontent.com/tangcent/easy-api/master/third/swagger.advanced.config
5 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/easy-api-kotlin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/easy-api-scala.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.ai.AIService:
--------------------------------------------------------------------------------
1 | com.itangcent.ai.OpenAIService
2 | com.itangcent.ai.DeepSeekService
3 | com.itangcent.ai.LocalLLMService
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.common.logger.ILogger:
--------------------------------------------------------------------------------
1 | #com.itangcent.debug.LoggerCollector
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.common.spi.SetupAble:
--------------------------------------------------------------------------------
1 | com.itangcent.intellij.spi.IdeaAutoInject
2 | com.itangcent.intellij.tip.OnlyOnceInContextTipSetup
3 | com.itangcent.intellij.jvm.kotlin.KotlinAutoInject
4 | com.itangcent.idea.psi.DisableDocSupport
5 | com.itangcent.suv.http.HttpClientScriptInterceptorSupport
6 | com.itangcent.intellij.context.AutoClearSupporter
7 | com.itangcent.ai.AIServiceCacheSupport
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.condition.Condition:
--------------------------------------------------------------------------------
1 | com.itangcent.idea.condition.OnClassCondition
2 | com.itangcent.idea.condition.OnMissingClassCondition
3 | com.itangcent.idea.plugin.api.export.condition.OnChannelCondition
4 | com.itangcent.idea.plugin.api.export.condition.OnDocCondition
5 | com.itangcent.idea.plugin.api.export.condition.OnSimpleCondition
6 | com.itangcent.idea.plugin.condition.OnSettingCondition
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.idea.plugin.Initializer:
--------------------------------------------------------------------------------
1 | com.itangcent.idea.plugin.settings.EnumProcessInitializer
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.idea.plugin.api.export.core.ClassExporter:
--------------------------------------------------------------------------------
1 | com.itangcent.idea.plugin.api.export.spring.SimpleSpringRequestClassExporter
2 | com.itangcent.idea.plugin.api.export.spring.SpringRequestClassExporter
3 | com.itangcent.idea.plugin.api.export.spring.ActuatorEndpointExporter
4 | com.itangcent.idea.plugin.api.export.feign.FeignRequestClassExporter
5 | com.itangcent.idea.plugin.api.export.feign.SimpleFeignRequestClassExporter
6 | com.itangcent.idea.plugin.api.export.jaxrs.JAXRSRequestClassExporter
7 | com.itangcent.idea.plugin.api.export.jaxrs.SimpleJAXRSRequestClassExporter
8 | com.itangcent.idea.plugin.api.export.generic.GenericMethodDocClassExporter
9 | com.itangcent.idea.plugin.api.export.generic.GenericRequestClassExporter
10 | com.itangcent.idea.plugin.api.export.generic.SimpleGenericMethodDocClassExporter
11 | com.itangcent.idea.plugin.api.export.generic.SimpleGenericRequestClassExporter
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.idea.plugin.api.export.core.MethodDocBuilderListener:
--------------------------------------------------------------------------------
1 | com.itangcent.idea.plugin.api.export.core.DefaultMethodDocBuilderListener
2 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.idea.plugin.api.export.core.RequestBuilderListener:
--------------------------------------------------------------------------------
1 | com.itangcent.idea.plugin.api.export.core.DefaultRequestBuilderListener
2 | com.itangcent.idea.plugin.api.export.postman.PostmanRequestBuilderListener
3 | com.itangcent.idea.plugin.api.export.translation.TranslationRequestBuilderListener
4 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.idea.plugin.api.export.spring.SpringControllerAnnotationResolver:
--------------------------------------------------------------------------------
1 | com.itangcent.idea.plugin.api.export.spring.StandardSpringControllerAnnotationResolver
2 | com.itangcent.idea.plugin.api.export.spring.CustomSpringControllerAnnotationResolver
3 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.idea.plugin.api.export.spring.SpringRequestMappingResolver:
--------------------------------------------------------------------------------
1 | com.itangcent.idea.plugin.api.export.spring.StandardSpringRequestMappingResolver
2 | com.itangcent.idea.plugin.api.export.spring.CustomSpringRequestMappingResolver
3 | com.itangcent.idea.plugin.api.export.feign.RequestLineRequestMappingResolver
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.intellij.CustomInfo:
--------------------------------------------------------------------------------
1 | com.itangcent.idea.plugin.CustomInfoImpl
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.intellij.config.ConfigProvider:
--------------------------------------------------------------------------------
1 | com.itangcent.idea.plugin.config.RecommendConfigProvider
2 | com.itangcent.idea.plugin.config.BuiltinConfigProvider
3 | com.itangcent.idea.plugin.config.RemoteConfigProvider
4 | com.itangcent.idea.plugin.config.RuntimeConfigProvider
5 | com.itangcent.idea.plugin.api.export.core.EasyApiConfigProvider
6 | com.itangcent.idea.plugin.api.export.postman.PostmanConfigProvider
7 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/META-INF/services/com.itangcent.suv.http.HttpClientProvider:
--------------------------------------------------------------------------------
1 | com.itangcent.suv.http.ApacheHttpClientProvider
2 | com.itangcent.suv.http.OkHttpClientProvider
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/class.svg:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/close.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/collapseall.svg:
--------------------------------------------------------------------------------
1 |
2 |
9 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/export.svg:
--------------------------------------------------------------------------------
1 |
2 |
12 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/import.svg:
--------------------------------------------------------------------------------
1 |
2 |
12 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/link.svg:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/method.svg:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/module.svg:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/moduleGroup.svg:
--------------------------------------------------------------------------------
1 |
2 |
11 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/ok.svg:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/refresh.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/remove.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/run.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/upFolder.svg:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/idea-plugin/src/main/resources/assets/webFolder.svg:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/condition/DefaultConditionEvaluatorTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.condition
2 |
3 | import com.itangcent.intellij.context.ActionContext
4 | import org.junit.jupiter.api.Test
5 | import org.mockito.kotlin.mock
6 | import kotlin.reflect.KClass
7 | import kotlin.test.assertFalse
8 | import kotlin.test.assertTrue
9 |
10 | /**
11 | * Test case of [DefaultConditionEvaluator]
12 | */
13 | internal class DefaultConditionEvaluatorTest {
14 |
15 | @Test
16 | fun matches() {
17 | val actionContext = mock()
18 | MyCondition.matches = false
19 | assertFalse(DefaultConditionEvaluator().matches(actionContext, FakeBeanService::class))
20 | MyCondition.matches = true
21 | assertTrue(DefaultConditionEvaluator().matches(actionContext, FakeBeanService::class))
22 | }
23 | }
24 |
25 | @Conditional(MyCondition::class)
26 | class FakeBeanService {
27 |
28 | }
29 |
30 | class MyCondition : Condition {
31 | override fun matches(actionContext: ActionContext, beanClass: KClass<*>): Boolean {
32 | return matches
33 | }
34 |
35 | companion object {
36 | var matches = false
37 | }
38 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/debug/LoggerCollectorTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.debug
2 |
3 | import com.itangcent.intellij.context.ActionContextBuilder
4 | import com.itangcent.intellij.extend.guice.with
5 | import com.itangcent.intellij.logger.Logger
6 | import com.itangcent.mock.BaseContextTest
7 | import org.junit.jupiter.api.Test
8 | import kotlin.test.assertEquals
9 |
10 | /**
11 | * Test case with [LoggerCollector]
12 | */
13 | internal class LoggerCollectorTest : BaseContextTest() {
14 |
15 | override fun bind(builder: ActionContextBuilder) {
16 | super.bind(builder)
17 | builder.bind(Logger::class) { it.with(LoggerCollector::class) }
18 | }
19 |
20 | @Test
21 | fun testLog() {
22 | logger.debug("hello")
23 | logger.info("world")
24 | assertEquals(
25 | "[DEBUG]\thello\n" +
26 | "[INFO]\tworld\n", LoggerCollector.getLog()
27 | )
28 | }
29 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/condition/OnClassConditionTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.condition
2 |
3 | import com.itangcent.idea.condition.annotation.ConditionOnClass
4 | import com.itangcent.testFramework.PluginContextLightCodeInsightFixtureTestCase
5 |
6 | /**
7 | * Test case of [OnClassCondition]
8 | */
9 | internal class OnClassConditionTest : PluginContextLightCodeInsightFixtureTestCase() {
10 |
11 | override fun beforeBind() {
12 | super.beforeBind()
13 | loadClass("spring/RequestMapping.java")
14 | }
15 |
16 | fun testMatches() {
17 | val onClassCondition = OnClassCondition()
18 | assertTrue(onClassCondition.matches(actionContext, ConditionOnRequestMapping::class))
19 | assertFalse(onClassCondition.matches(actionContext, ConditionOnRestController::class))
20 | }
21 |
22 | @ConditionOnClass("org.springframework.web.bind.annotation.RequestMapping")
23 | class ConditionOnRequestMapping
24 |
25 | @ConditionOnClass("org.springframework.web.bind.annotation.RestController")
26 | class ConditionOnRestController
27 | }
28 |
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/condition/OnMissingClassConditionTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.condition
2 |
3 | import com.itangcent.idea.condition.annotation.ConditionOnMissingClass
4 | import com.itangcent.testFramework.PluginContextLightCodeInsightFixtureTestCase
5 |
6 | /**
7 | * Test case of [OnMissingClassCondition]
8 | */
9 | internal class OnMissingClassConditionTest : PluginContextLightCodeInsightFixtureTestCase() {
10 |
11 | override fun beforeBind() {
12 | super.beforeBind()
13 | loadClass("spring/RequestMapping.java")
14 | }
15 |
16 | fun testMatches() {
17 | val onMissingClassCondition = OnMissingClassCondition()
18 | assertFalse(onMissingClassCondition.matches(actionContext, ConditionOnRequestMapping::class))
19 | assertTrue(onMissingClassCondition.matches(actionContext, ConditionOnRestController::class))
20 | }
21 |
22 | @ConditionOnMissingClass("org.springframework.web.bind.annotation.RequestMapping")
23 | class ConditionOnRequestMapping
24 |
25 | @ConditionOnMissingClass("org.springframework.web.bind.annotation.RestController")
26 | class ConditionOnRestController
27 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/CustomInfoImplTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin
2 |
3 | import com.itangcent.common.spi.SpiUtils
4 | import com.itangcent.intellij.CustomInfo
5 | import org.junit.jupiter.api.Assertions.assertEquals
6 | import org.junit.jupiter.api.Test
7 |
8 | internal class CustomInfoImplTest {
9 |
10 | @Test
11 | fun pluginName() {
12 | assertEquals("easy-api", SpiUtils.loadService(CustomInfo::class)
13 | !!.pluginName())
14 | }
15 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/core/AdditionalParseHelperTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.api.export.core
2 |
3 | import com.google.inject.Inject
4 | import com.itangcent.intellij.context.ActionContextBuilder
5 | import com.itangcent.intellij.extend.guice.with
6 | import com.itangcent.mock.BaseContextTest
7 | import kotlin.reflect.KClass
8 |
9 | /**
10 | * Test case with [AdditionalParseHelper]
11 | */
12 | abstract class AdditionalParseHelperTest : BaseContextTest() {
13 |
14 | @Inject
15 | protected lateinit var additionalParseHelper: AdditionalParseHelper
16 |
17 | abstract val additionalParseHelperClass: KClass
18 |
19 | override fun bind(builder: ActionContextBuilder) {
20 | super.bind(builder)
21 | builder.bind(AdditionalParseHelper::class) { it.with(additionalParseHelperClass) }
22 | }
23 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/core/EasyApiConfigProviderTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.api.export.core
2 |
3 | import com.itangcent.intellij.config.ConfigProvider
4 | import com.itangcent.intellij.config.ConfigProviderTest
5 | import org.junit.jupiter.api.Test
6 | import kotlin.reflect.KClass
7 | import kotlin.test.assertEquals
8 |
9 | /**
10 | * Test case of [EasyApiConfigProvider]
11 | */
12 | internal class EasyApiConfigProviderTest : ConfigProviderTest() {
13 | override val configProviderClass: KClass
14 | get() = EasyApiConfigProvider::class
15 |
16 | @Test
17 | fun testConfig() {
18 | assertEquals(
19 | resourceId("config/a/.easy.api.config") + "\n" +
20 | resourceId("config/a/.easy.api.yml") + "\n" +
21 | resourceId("config/a/.easy.api.yaml") + "\n" +
22 | resourceId("config/.easy.api.config") + "\n" +
23 | resourceId("config/.easy.api.yml") + "\n" +
24 | resourceId("config/.easy.api.yaml"),
25 | configProvider.loadConfig().joinToString("\n") { it.id })
26 | }
27 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/api/export/postman/PostmanWorkspaceTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.api.export.postman
2 |
3 | import com.itangcent.idea.plugin.api.export.postman.Emojis.PERSONAL
4 | import com.itangcent.idea.plugin.api.export.postman.Emojis.TEAM
5 | import org.junit.jupiter.api.Assertions.assertEquals
6 | import org.junit.jupiter.api.Assertions.assertNull
7 | import org.junit.jupiter.api.Test
8 |
9 | /**
10 | * Test case of [PostmanWorkspace]
11 | */
12 | internal class PostmanWorkspaceTest {
13 |
14 | @Test
15 | fun nameWithType() {
16 | val postmanWorkspace = PostmanWorkspace("001", null, null)
17 | assertNull(postmanWorkspace.nameWithType())
18 | postmanWorkspace.name = "My Workspace"
19 | assertEquals("My Workspace", postmanWorkspace.nameWithType())
20 | postmanWorkspace.type = "team"
21 | assertEquals("${TEAM}My Workspace", postmanWorkspace.nameWithType())
22 | postmanWorkspace.type = "personal"
23 | assertEquals("${PERSONAL}My Workspace", postmanWorkspace.nameWithType())
24 | }
25 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/rule/ScriptExplicitClassContextTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.rule
2 |
3 | import com.google.inject.Inject
4 | import com.intellij.psi.PsiClass
5 | import com.itangcent.idea.plugin.rule.ScriptRuleParser.ScriptClassContext
6 | import com.itangcent.idea.plugin.rule.ScriptRuleParser.ScriptExplicitClassContext
7 | import com.itangcent.intellij.jvm.DuckTypeHelper
8 |
9 | /**
10 | * Test case of [ScriptExplicitClassContext]
11 | */
12 | class ScriptExplicitClassContextTest : ScriptClassContextBaseTest() {
13 |
14 | @Inject
15 | private lateinit var duckTypeHelper: DuckTypeHelper
16 |
17 | override fun PsiClass.asClassContext(): ScriptClassContext {
18 | return ruleParser.contextOf(duckTypeHelper.explicit(this), this) as ScriptClassContext
19 | }
20 |
21 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/rule/ScriptPsiClassContextTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.rule
2 |
3 | import com.intellij.psi.PsiClass
4 | import com.itangcent.idea.plugin.rule.ScriptRuleParser.ScriptClassContext
5 | import com.itangcent.idea.plugin.rule.ScriptRuleParser.ScriptPsiClassContext
6 |
7 | /**
8 | * Test case of [ScriptPsiClassContext]
9 | */
10 | class ScriptPsiClassContextTest : ScriptClassContextBaseTest() {
11 |
12 | override fun PsiClass.asClassContext(): ScriptClassContext {
13 | return ruleParser.contextOf(this, this) as ScriptClassContext
14 | }
15 |
16 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/rule/ScriptPsiTypeContextTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.rule
2 |
3 | import com.intellij.psi.PsiClass
4 | import com.intellij.psi.util.PsiTypesUtil
5 | import com.itangcent.idea.plugin.rule.ScriptRuleParser.ScriptClassContext
6 | import com.itangcent.idea.plugin.rule.ScriptRuleParser.ScriptPsiTypeContext
7 |
8 | /**
9 | * Test case of [ScriptPsiTypeContext]
10 | */
11 | class ScriptPsiTypeContextTest : ScriptClassContextBaseTest() {
12 |
13 | override fun PsiClass.asClassContext(): ScriptClassContext {
14 | return ruleParser.contextOf(PsiTypesUtil.getClassType(this), this) as ScriptClassContext
15 | }
16 |
17 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/settings/EventRecordsTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.settings
2 |
3 | import com.itangcent.testFramework.PluginContextLightCodeInsightFixtureTestCase
4 |
5 | /**
6 | * Test case of [EventRecords]
7 | */
8 | internal class EventRecordsTest : PluginContextLightCodeInsightFixtureTestCase() {
9 |
10 | fun testRecord() {
11 | assertEquals(EventRecords.getRecord("com.itangcent.test.record"), 0)
12 | assertEquals(EventRecords.record("com.itangcent.test.record"), 1)
13 | assertEquals(EventRecords.getRecord("com.itangcent.test.record"), 1)
14 | assertEquals(EventRecords.record("com.itangcent.test.record"), 2)
15 | assertEquals(EventRecords.getRecord("com.itangcent.test.record"), 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/settings/SettingsTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.settings
2 |
3 | import org.junit.jupiter.api.Test
4 |
5 | /**
6 | * Test case of [Settings]
7 | */
8 | internal class SettingsTest {
9 |
10 | @Test
11 | fun testCETH() {
12 | val original = Settings()
13 | original.pullNewestDataBefore = true
14 |
15 | ETHUtils.testCETH(original) { copy() }
16 | }
17 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/settings/helper/BuiltInConfigSettingsHelperTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.settings.helper
2 |
3 | import com.google.inject.Inject
4 | import org.junit.jupiter.api.Test
5 | import kotlin.test.assertEquals
6 |
7 | /**
8 | * Test case of [BuiltInConfigSettingsHelper]
9 | */
10 | internal class BuiltInConfigSettingsHelperTest : SettingsHelperTest() {
11 |
12 | @Inject
13 | private lateinit var builtInConfigSettingsHelper: BuiltInConfigSettingsHelper
14 |
15 | @Test
16 | fun testBuiltInConfig() {
17 | settings.builtInConfig = "hello world"
18 | assertEquals("hello world", builtInConfigSettingsHelper.builtInConfig())
19 | settings.builtInConfig = "test-demo"
20 | assertEquals("test-demo", builtInConfigSettingsHelper.builtInConfig())
21 | }
22 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/settings/helper/SettingsHelperTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.settings.helper
2 |
3 | import com.itangcent.idea.plugin.settings.SettingBinder
4 | import com.itangcent.idea.plugin.settings.Settings
5 | import com.itangcent.intellij.context.ActionContextBuilder
6 | import com.itangcent.mock.AdvancedContextTest
7 | import com.itangcent.mock.SettingBinderAdaptor
8 |
9 | /**
10 | * Test case of [*SettingsHelper]
11 | */
12 | abstract class SettingsHelperTest : AdvancedContextTest() {
13 |
14 | internal val settings = Settings()
15 |
16 | override fun bind(builder: ActionContextBuilder) {
17 | super.bind(builder)
18 | builder.bind(SettingBinder::class) { it.toInstance(SettingBinderAdaptor(settings)) }
19 | }
20 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/settings/helper/SupportSettingsHelperTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.settings.helper
2 |
3 | import com.google.inject.Inject
4 | import org.junit.jupiter.api.Test
5 | import kotlin.test.assertFalse
6 | import kotlin.test.assertTrue
7 |
8 | /**
9 | * Test case of [SupportSettingsHelper]
10 | */
11 | internal class SupportSettingsHelperTest : SettingsHelperTest() {
12 |
13 | @Inject
14 | private lateinit var supportSettingsHelper: SupportSettingsHelper
15 |
16 | @Test
17 | fun testMethodDocEnable() {
18 | settings.methodDocEnable = true
19 | assertTrue(supportSettingsHelper.methodDocEnable())
20 | settings.methodDocEnable = false
21 | assertFalse(supportSettingsHelper.methodDocEnable())
22 | }
23 |
24 | @Test
25 | fun testGenericEnable() {
26 | settings.genericEnable = true
27 | assertTrue(supportSettingsHelper.genericEnable())
28 | settings.genericEnable = false
29 | assertFalse(supportSettingsHelper.genericEnable())
30 | }
31 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/utils/LocalStorageTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.utils
2 |
3 | /**
4 | * Test case of [LocalStorage]
5 | */
6 | class LocalStorageTest : AbstractStorageTest() {
7 | override val storageClass = LocalStorage::class
8 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/plugin/utils/SessionStorageTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.plugin.utils
2 |
3 | /**
4 | * Test case of [SessionStorage]
5 | */
6 | class SessionStorageTest : AbstractStorageTest() {
7 | override val storageClass = SessionStorage::class
8 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/psi/PsiMethodUtilTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.psi
2 |
3 | import com.intellij.psi.PsiClass
4 | import com.itangcent.testFramework.PluginContextLightCodeInsightFixtureTestCase
5 | import org.junit.Assert
6 |
7 | /**
8 | * Test case of [PsiMethodUtil]
9 | */
10 | internal class PsiMethodUtilTest : PluginContextLightCodeInsightFixtureTestCase() {
11 |
12 | private lateinit var resultPsiClass: PsiClass
13 | private lateinit var iResultPsiClass: PsiClass
14 |
15 | override fun beforeBind() {
16 | super.beforeBind()
17 |
18 | iResultPsiClass = loadClass("model/IResult.java")!!
19 | resultPsiClass = loadClass("model/Result.java")!!
20 | }
21 |
22 | fun testIsSuperMethod() {
23 | assertTrue(PsiMethodUtil.isSuperMethod(
24 | resultPsiClass.methods.first { it.name == "getCode" },
25 | iResultPsiClass.methods.first { it.name == "getCode" }
26 | ))
27 | assertFalse(PsiMethodUtil.isSuperMethod(
28 | resultPsiClass.methods.first { it.name == "fail" },
29 | resultPsiClass.methods.last { it.name == "fail" }
30 | ))
31 | }
32 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/utils/ConfigurableLoggerTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.utils
2 |
3 | import com.itangcent.debug.LoggerCollector
4 | import com.itangcent.idea.plugin.settings.helper.CommonSettingsHelper
5 | import com.itangcent.logger.ConfigurableLogger
6 | import org.junit.jupiter.params.ParameterizedTest
7 | import org.junit.jupiter.params.provider.CsvSource
8 | import kotlin.test.assertEquals
9 |
10 | /**
11 | * Test case of [com.itangcent.logger.ConfigurableLogger]
12 | */
13 | internal class ConfigurableLoggerTest {
14 |
15 | @ParameterizedTest
16 | @CsvSource(
17 | "VERBOSE,[TRACE]\ttrace[DEBUG]\tdebug[INFO]\tinfo[WARN]\twarn[ERROR]\terror[INFO]\tlog",
18 | "NORMAL,[INFO]\tinfo[WARN]\twarn[ERROR]\terror[INFO]\tlog",
19 | "QUIET,[ERROR]\terror",
20 | )
21 | fun testLog(level: CommonSettingsHelper.VerbosityLevel, output: String) {
22 | val logger = ConfigurableLogger(
23 | LoggerCollector(),
24 | level.level
25 | )
26 | logger.trace("trace")
27 | logger.debug("debug")
28 | logger.info("info")
29 | logger.warn("warn")
30 | logger.error("error")
31 | logger.log("log")
32 | assertEquals(output, LoggerCollector.getLog().replace("\n", ""))
33 | }
34 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/utils/DefaultSystemProviderTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.utils
2 |
3 | import com.google.inject.Inject
4 | import com.itangcent.intellij.context.ActionContextBuilder
5 | import com.itangcent.intellij.extend.guice.with
6 | import com.itangcent.mock.AdvancedContextTest
7 | import org.junit.jupiter.api.Test
8 | import kotlin.math.abs
9 | import kotlin.test.assertEquals
10 | import kotlin.test.assertTrue
11 |
12 | /**
13 | * Test case of [DefaultSystemProvider]
14 | */
15 | internal class DefaultSystemProviderTest : AdvancedContextTest() {
16 |
17 | @Inject
18 | private lateinit var systemProvider: SystemProvider
19 |
20 | override fun bind(builder: ActionContextBuilder) {
21 | super.bind(builder)
22 | builder.bind(SystemProvider::class) { it.with(DefaultSystemProvider::class) }
23 | }
24 |
25 | @Test
26 | fun testCurrentTimeMillis() {
27 | assertTrue(abs(systemProvider.currentTimeMillis() - System.currentTimeMillis()) < 5)
28 | }
29 |
30 | @Test
31 | fun testRunTime() {
32 | assertEquals(Runtime.getRuntime(), systemProvider.runtime())
33 | }
34 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/utils/IOUtilsTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.utils
2 |
3 | import org.junit.jupiter.api.Test
4 |
5 |
6 | /**
7 | * Test case for [IOUtils]
8 | */
9 | class IOUtilsTest {
10 |
11 | @Test
12 | fun testGetEncodingName() {
13 | // assertEquals("UTF-8", IOUtils.getEncodingName("utf-8".toByteArray(Charsets.UTF_8)))
14 | }
15 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/idea/utils/ProjectHelperTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.idea.utils
2 |
3 | import com.itangcent.testFramework.ContextLightCodeInsightFixtureTestCase
4 | import org.junit.jupiter.api.Test
5 |
6 | /**
7 | * Test case for [ProjectHelper]
8 | */
9 | internal class ProjectHelperTest : ContextLightCodeInsightFixtureTestCase() {
10 |
11 | fun testGetCurrentProject() {
12 | assertEquals(project, ProjectHelper.getCurrentProject(null))
13 | }
14 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/intellij/extend/ThrottleKitTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.intellij.extend
2 |
3 | import com.itangcent.intellij.extend.rx.throttle
4 | import org.junit.jupiter.api.Assertions.assertFalse
5 | import org.junit.jupiter.api.Assertions.assertTrue
6 | import org.junit.jupiter.api.Test
7 | import org.junit.jupiter.api.assertTimeout
8 | import java.time.Duration
9 |
10 |
11 | /**
12 | * Test case for [ThrottleKit]
13 | */
14 | class ThrottleKitTest {
15 |
16 | @Test
17 | fun testAcquireGreedy() {
18 | val throttle = throttle()
19 | throttle.acquire(1000)
20 | val now = System.currentTimeMillis()
21 | assertTimeout(Duration.ofMillis(10)) { throttle.acquire(1000) }
22 | assertFalse(throttle.acquire(1000))
23 | throttle.acquireGreedy(1000)
24 | assertTrue(now + 99 <= System.currentTimeMillis())
25 | Thread.sleep(1000)
26 | assertTrue(throttle.acquire(1000))
27 | }
28 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/intellij/util/CacheAbleTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.intellij.util
2 |
3 | import org.junit.jupiter.api.Assertions.assertEquals
4 | import org.junit.jupiter.api.Test
5 |
6 |
7 | /**
8 | * Test case for [CacheAble]
9 | */
10 | class CacheAbleTest {
11 |
12 | @Test
13 | fun testCache() {
14 | val cacheAble: CacheAble = DefaultCacheAle()
15 |
16 | assertEquals("str", cacheAble.cache("str") { "str" })
17 | assertEquals("str", cacheAble.cache("str") { })
18 | assertEquals("str", cacheAble.cache("str") { 1 })
19 |
20 | var cnt = 0
21 | assertEquals("str", cacheAble.cache("str") { cnt++ })
22 | assertEquals(0, cnt)
23 |
24 | assertEquals(null, cacheAble.cache("null") { null })
25 | assertEquals(null, cacheAble.cache("null") { 1 })
26 | }
27 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/intellij/util/FileTypeTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.intellij.util
2 |
3 | import com.itangcent.mock.BaseContextTest
4 | import org.junit.jupiter.api.Assertions.assertFalse
5 | import org.junit.jupiter.api.Assertions.assertTrue
6 | import org.junit.jupiter.api.Test
7 |
8 | /**
9 | * Test case of [FileType]
10 | */
11 | internal class FileTypeTest : BaseContextTest() {
12 |
13 | @Test
14 | fun suffix() {
15 | assertTrue(FileType.acceptable("xxxx.java"))
16 | assertTrue(FileType.acceptable("xxxx.kt"))
17 | assertFalse(FileType.acceptable("xxxx.scala"))
18 | }
19 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/mock/ConstantModuleHelper.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.mock
2 |
3 | import com.google.inject.Singleton
4 | import com.intellij.psi.PsiClass
5 | import com.intellij.psi.PsiFile
6 | import com.intellij.psi.PsiMethod
7 | import com.itangcent.idea.utils.ModuleHelper
8 |
9 | @Singleton
10 | class ConstantModuleHelper(private val module: String) : ModuleHelper {
11 |
12 | override fun findModule(resource: Any): String {
13 | return module
14 | }
15 |
16 | override fun findModule(psiMethod: PsiMethod): String {
17 | return module
18 | }
19 |
20 | override fun findModule(cls: PsiClass): String {
21 | return module
22 | }
23 |
24 | override fun findModule(psiFile: PsiFile): String {
25 | return module
26 | }
27 |
28 | override fun findModuleByPath(path: String?): String {
29 | return module
30 | }
31 |
32 | companion object {
33 | val INSTANCE = ConstantModuleHelper("test_default")
34 | }
35 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/mock/CrossPlatformKit.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.mock
2 |
3 | fun String.toUnixString(): String {
4 | if (LINE_SEPARATOR == "\n") {
5 | return this
6 | }
7 | return this.replace(LINE_SEPARATOR, "\n")
8 | }
9 |
10 | private val LINE_SEPARATOR = System.getProperty("line.separator")
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/mock/FakeExportContext.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.mock
2 |
3 | import com.intellij.psi.PsiElement
4 | import com.itangcent.idea.plugin.api.export.core.ExportContext
5 | import com.itangcent.idea.plugin.api.export.core.RootExportContext
6 |
7 | class FakeExportContext: ExportContext , RootExportContext() {
8 | override fun psi(): PsiElement {
9 | TODO("Not yet implemented")
10 | }
11 |
12 | companion object{
13 | val INSTANCE = FakeExportContext()
14 | }
15 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/mock/ImmutableSystemProvider.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.mock
2 |
3 | import com.google.inject.Singleton
4 | import com.itangcent.idea.utils.SystemProvider
5 |
6 | @Singleton
7 | class ImmutableSystemProvider : SystemProvider {
8 |
9 | var currentTimeMillis: Long? = null
10 |
11 | var runtime: Runtime? = null
12 |
13 | constructor(currentTimeMillis: Long) {
14 | this.currentTimeMillis = currentTimeMillis
15 | }
16 |
17 | override fun currentTimeMillis(): Long {
18 | return currentTimeMillis ?: System.currentTimeMillis();
19 | }
20 |
21 | override fun runtime(): Runtime {
22 | return runtime ?: Runtime.getRuntime()
23 | }
24 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/mock/MockKit.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.mock
2 |
3 | import com.itangcent.intellij.jvm.adapt.getterPropertyName
4 | import com.itangcent.intellij.jvm.adapt.maybeGetterMethodPropertyName
5 | import com.itangcent.intellij.jvm.adapt.maybeSetterMethodPropertyName
6 | import com.itangcent.intellij.jvm.adapt.setterPropertyName
7 | import org.mockito.stubbing.Answer
8 |
9 | inline fun any(t: T): T {
10 | org.mockito.kotlin.any()
11 | return t
12 | }
13 |
14 | fun mockFields(): Answer<*> {
15 | val data = hashMapOf()
16 | return Answer {
17 | val name = it.method.name
18 | if (name.maybeGetterMethodPropertyName()) {
19 | return@Answer data[name.getterPropertyName()]
20 | } else if (name.maybeSetterMethodPropertyName()) {
21 | data[name.setterPropertyName()] = it.arguments[0]
22 | return@Answer null
23 | } else {
24 | return@Answer null
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/mock/SettingBinderAdaptor.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.mock
2 |
3 | import com.google.inject.Singleton
4 | import com.itangcent.idea.plugin.settings.SettingBinder
5 | import com.itangcent.idea.plugin.settings.Settings
6 |
7 | @Singleton
8 | class SettingBinderAdaptor : SettingBinder {
9 |
10 | private var settings: Settings
11 |
12 | constructor(settings: Settings) {
13 | this.settings = settings
14 | }
15 |
16 | constructor() {
17 | this.settings = Settings()
18 | }
19 |
20 | override fun read(): Settings {
21 | return settings
22 | }
23 |
24 | override fun save(t: Settings?) {
25 | if (t != null) {
26 | this.settings = t
27 | }
28 | }
29 |
30 | override fun tryRead(): Settings? {
31 | return settings
32 | }
33 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/test/ActionContextKit.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.test
2 |
3 | import org.mockito.Mockito
4 | import org.mockito.kotlin.KStubbing
5 | import org.mockito.kotlin.mock
6 | import org.mockito.kotlin.stub
7 | import kotlin.reflect.KClass
8 |
9 | @Suppress("UNCHECKED_CAST")
10 | fun com.itangcent.intellij.context.ActionContextBuilder.mock(type: KClass<*>) {
11 | this.bindInstance(type as KClass, Mockito.mock(type.java) as Any)
12 | }
13 |
14 | @Suppress("UNCHECKED_CAST")
15 | fun com.itangcent.intellij.context.ActionContextBuilder.mock(
16 | type: KClass,
17 | mock: KStubbing.(T) -> Unit
18 | ) {
19 | val mockCls = type.java
20 | this.bindInstance(type as KClass, Mockito.mock(mockCls).also {
21 | KStubbing(it).mock(it)
22 | } as Any)
23 | }
24 |
25 | @Suppress("UNCHECKED_CAST")
26 | inline fun com.itangcent.intellij.context.ActionContextBuilder.mock(
27 | stubbing: KStubbing.(T) -> Unit
28 | ) {
29 | this.bindInstance(
30 | T::class as KClass,
31 | mock().stub(stubbing) as Any
32 | )
33 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/test/AssertKits.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.test
2 |
3 | import kotlin.test.assertEquals
4 | import kotlin.test.assertTrue
5 |
6 |
7 | fun assertContentEquals(expected: Array, actual: Array?) {
8 | assertTrue(expected.contentEquals(actual))
9 | }
10 |
11 | fun assertLinesEqualsIgnoreOrder(expected: String, actual: String) {
12 | val expectedLines = expected.lines()
13 | val actualLines = actual.lines()
14 | assertEquals(expectedLines.size, actualLines.size)
15 | assertEquals(expectedLines.sorted(), actualLines.sorted())
16 | }
17 |
18 | fun assertLinesContain(expected: String, actual: String) {
19 | val expectedLines = expected.lines()
20 | val actualLines = actual.lines().toHashSet()
21 | assertTrue(actualLines.containsAll(expectedLines))
22 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/test/ResultLoaderTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.test
2 |
3 | import org.junit.jupiter.api.Test
4 | import kotlin.test.assertEquals
5 |
6 | /**
7 | * Test case of [ResultLoader]
8 | */
9 | internal class ResultLoaderTest {
10 |
11 | @Test
12 | fun testLoad() {
13 | assertEquals("asdfghjkl", ResultLoader.load())
14 | assertEquals("123456789", ResultLoader.load("sub"))
15 | }
16 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/test/StringResource.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.test
2 |
3 | import com.itangcent.intellij.config.resource.Resource
4 | import java.io.InputStream
5 | import java.net.URL
6 |
7 | class StringResource(
8 | private val _url: String,
9 | private val str: String,
10 | ) : Resource() {
11 | override val url: URL
12 | get() = URL(_url)
13 |
14 | override val bytes: ByteArray
15 | get() = str.toByteArray(Charsets.UTF_8)
16 |
17 | override val content: String
18 | get() = str
19 |
20 | override val inputStream: InputStream
21 | get() = str.toByteArray(Charsets.UTF_8).inputStream()
22 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/testFramework/FileKit.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.testFramework
2 |
3 | import java.io.File
4 | import java.nio.file.Path
5 |
6 | private val separator = File.separator
7 |
8 | fun Path.sub(path: String): File {
9 | return File("$this/$path".r())
10 | }
11 |
12 | fun String.sub(path: String): String {
13 | return "$this/$path".r()
14 | }
15 |
16 | fun String.escapeBackslash(): String {
17 | return this.replace("\\", "\\\\")
18 | }
19 |
20 | /**
21 | * redirect to real path
22 | */
23 | fun String.r(): String {
24 | return this.replace("/", separator)
25 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/testFramework/PluginContextLightCodeInsightFixtureTestCase.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.testFramework
2 |
3 | import com.itangcent.idea.plugin.rule.SuvRuleParser
4 | import com.itangcent.idea.plugin.settings.SettingBinder
5 | import com.itangcent.idea.swing.MessagesHelper
6 | import com.itangcent.idea.utils.ModuleHelper
7 | import com.itangcent.intellij.config.rule.RuleParser
8 | import com.itangcent.intellij.context.ActionContextBuilder
9 | import com.itangcent.intellij.extend.guice.singleton
10 | import com.itangcent.intellij.extend.guice.with
11 | import com.itangcent.mock.ConstantModuleHelper
12 | import com.itangcent.mock.EmptyMessagesHelper
13 | import com.itangcent.mock.SettingBinderAdaptor
14 |
15 |
16 | abstract class PluginContextLightCodeInsightFixtureTestCase : ContextLightCodeInsightFixtureTestCase() {
17 |
18 | override fun bind(builder: ActionContextBuilder) {
19 | builder.bind(SettingBinder::class) { it.with(SettingBinderAdaptor::class) }
20 | builder.bind(RuleParser::class) { it.with(SuvRuleParser::class).singleton() }
21 | builder.bind(ModuleHelper::class) { it.toInstance(ConstantModuleHelper.INSTANCE) }
22 | builder.bind(MessagesHelper::class) { it.with(EmptyMessagesHelper::class).singleton() }
23 | }
24 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/utils/FileKitKtTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.utils
2 |
3 | import org.junit.jupiter.api.Assertions.assertEquals
4 | import org.junit.jupiter.api.Test
5 | import org.junit.jupiter.api.condition.EnabledOnOs
6 | import org.junit.jupiter.api.condition.OS
7 |
8 | /**
9 | * Test case for [FileKit]
10 | */
11 | class FileKitKtTest {
12 | @Test
13 | @EnabledOnOs(OS.WINDOWS, disabledReason = "Only for Windows")
14 | fun testLocalPath_windows() {
15 | val input = "/foo/bar"
16 | val expected = "\\foo\\bar"
17 | assertEquals(expected, input.localPath())
18 | }
19 |
20 | @Test
21 | @EnabledOnOs(value = [OS.LINUX, OS.MAC], disabledReason = "Only for Linux and Mac")
22 | fun testLocalPath_linux() {
23 | val input = "/foo/bar"
24 | assertEquals(input, input.localPath())
25 | }
26 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/utils/GiteeSupportTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.utils
2 |
3 | import org.junit.jupiter.api.Assertions.assertEquals
4 | import org.junit.jupiter.api.Assertions.assertNull
5 | import org.junit.jupiter.api.Test
6 |
7 | /**
8 | * Test case for [GiteeSupport]
9 | *
10 | * @author tangcent
11 | */
12 | internal class GiteeSupportTest {
13 |
14 | @Test
15 | fun testConvertUrlFromGithub() {
16 | val githubUrl = "https://raw.githubusercontent.com/user/project/file.txt"
17 | val expectedGiteeUrl = "https://gitee.com/user/project/raw/file.txt"
18 |
19 | val actualGiteeUrl = GiteeSupport.convertUrlFromGithub(githubUrl)
20 |
21 | assertEquals(expectedGiteeUrl, actualGiteeUrl)
22 | }
23 |
24 | @Test
25 | fun testInvalidUrl() {
26 | val invalidUrl = "some invalid url"
27 | val giteeUrl = GiteeSupport.convertUrlFromGithub(invalidUrl)
28 |
29 | assertNull(giteeUrl)
30 | }
31 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/utils/NonReentrantTest.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.utils
2 |
3 | import org.junit.jupiter.api.Assertions.assertEquals
4 | import org.junit.jupiter.api.Test
5 | import org.junit.jupiter.api.assertThrows
6 | import kotlin.concurrent.thread
7 |
8 | class NonReentrantTest {
9 |
10 | @Test
11 | fun testCall() {
12 | assertThrows {
13 | NonReentrant.call("test") {
14 | call()
15 | }
16 | }
17 | assertEquals("yes", call())
18 |
19 | val threadA = thread {
20 | NonReentrant.call("test") {
21 | Thread.sleep(1000)
22 | }
23 | }
24 | val threadB = thread {
25 | NonReentrant.call("test") {
26 | Thread.sleep(1000)
27 | }
28 | }
29 | threadA.join()
30 | threadB.join()
31 | }
32 |
33 | private fun call() = NonReentrant.call("test") {
34 | "yes"
35 | }
36 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/kotlin/com/itangcent/utils/WaitHelper.kt:
--------------------------------------------------------------------------------
1 | package com.itangcent.utils
2 |
3 | import kotlin.test.fail
4 |
5 | object WaitHelper {
6 |
7 | fun waitUtil(timeOut: Long, condition: () -> Boolean) {
8 | val t = System.currentTimeMillis() + timeOut
9 | while (true) {
10 | if (condition()) {
11 | return
12 | }
13 | if (System.currentTimeMillis() > t) {
14 | break
15 | }
16 | Thread.sleep(200)
17 | }
18 | fail()
19 | }
20 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/resources/META-INF/services/com.itangcent.idea.icons.IconLoader:
--------------------------------------------------------------------------------
1 | com.itangcent.test.IconLoaderHeadlessSupport
--------------------------------------------------------------------------------
/idea-plugin/src/test/resources/META-INF/services/com.itangcent.spi.MyService:
--------------------------------------------------------------------------------
1 | com.itangcent.spi.MyService1
2 | com.itangcent.spi.MyService2
--------------------------------------------------------------------------------
/idea-plugin/src/test/resources/annotation/MyController.java:
--------------------------------------------------------------------------------
1 | package api.annotation;
2 |
3 | import org.springframework.core.annotation.AliasFor;
4 | import org.springframework.web.bind.annotation.RestController;
5 |
6 | import java.lang.annotation.Documented;
7 | import java.lang.annotation.ElementType;
8 | import java.lang.annotation.Retention;
9 | import java.lang.annotation.RetentionPolicy;
10 | import java.lang.annotation.Target;
11 |
12 | @Target({ElementType.TYPE})
13 | @Retention(RetentionPolicy.RUNTIME)
14 | @Documented
15 | @RestController
16 | public @interface MyController {
17 | @AliasFor(annotation = RestController.class)
18 | String value() default "";
19 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/resources/annotation/Public.java:
--------------------------------------------------------------------------------
1 | package com.itangcent.annotation;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.Target;
6 |
7 | import static java.lang.annotation.ElementType.METHOD;
8 | import static java.lang.annotation.ElementType.TYPE;
9 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
10 |
11 | /**
12 | * Announce the interface as public
13 | */
14 | @Documented
15 | @Retention(RUNTIME)
16 | @Target({TYPE, METHOD})
17 | public @interface Public {
18 | }
19 |
--------------------------------------------------------------------------------
/idea-plugin/src/test/resources/api/BaseController.java:
--------------------------------------------------------------------------------
1 | package com.itangcent.api;
2 |
3 | import org.springframework.web.bind.annotation.RequestMapping;
4 |
5 | @RequestMapping("/")
6 | public class BaseController {
7 |
8 | /**
9 | * current ctrl name
10 | *
11 | * @public
12 | */
13 | @RequestMapping("/ctrl/name")
14 | public String ctrlName() {
15 | return getClass().getName();
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/idea-plugin/src/test/resources/api/CustomCtrl.java:
--------------------------------------------------------------------------------
1 | package api.annotation;
2 |
3 | import api.annotation.MyController;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 |
6 | @MyController
7 | public class CustomCtrl {
8 |
9 | @RequestMapping(value = "/hello")
10 | public String hello() {
11 | return "Hello, World!";
12 | }
13 | }
--------------------------------------------------------------------------------
/idea-plugin/src/test/resources/api/IUserApi.java:
--------------------------------------------------------------------------------
1 |
2 | package com.itangcent.api;
3 |
4 |
5 | import com.itangcent.model.Result;
6 | import org.springframework.web.bind.annotation.PostMapping;
7 | import org.springframework.web.bind.annotation.RequestBody;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 |
10 | import java.util.ArrayList;
11 |
12 | /**
13 | * api interface
14 | */
15 | @RequestMapping(value = "user")
16 | public interface IUserApi {
17 |
18 | @PostMapping(value = "/auth/loginAuth")
19 | Result loginAuth(@RequestBody Req req);
20 |
21 | /**
22 | * A default api
23 | * It is not necessary to implement it
24 | *
25 | * @param req request
26 | * @return response
27 | */
28 | @PostMapping(value = "/default")
29 | default Result> defaultApi(@RequestBody List req) {
30 | return Result.success(new ArrayList<>());
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/idea-plugin/src/test/resources/api/InferDemoCtrl.java:
--------------------------------------------------------------------------------
1 | package com.itangcent.api;
2 |
3 |
4 | import com.itangcent.api.BaseController;
5 | import com.itangcent.model.Result;
6 |
7 | import java.util.HashMap;
8 | import java.util.LinkedList;
9 | import java.util.List;
10 | import java.util.Map;
11 |
12 | /**
13 | * infer demo
14 | */
15 | @RestController
16 | @RequestMapping(value = "infer")
17 | public class InferDemoCtrl extends BaseController {
18 |
19 | /**
20 | * Infer the response that contains the collection
21 | */
22 | @RequestMapping(value = "/interWithCollection", method = RequestMethod.POST)
23 | public Object interWithCollection(@PathVariable("id") Long id) {
24 | List