diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7e629e58..6e49ca94 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,7 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true - + jobs: # Prepare environment and build the plugin @@ -36,13 +36,13 @@ jobs: pluginVerifierHomeDir: ${{ steps.properties.outputs.pluginVerifierHomeDir }} steps: - # Check out current repository + # Check out the current repository - name: Fetch Sources uses: actions/checkout@v4 # Validate wrapper - name: Gradle Wrapper Validation - uses: gradle/wrapper-validation-action@v3 + uses: gradle/actions/wrapper-validation@v3 # Set up Java environment for the next steps - name: Setup Java @@ -54,8 +54,6 @@ jobs: # Setup Gradle - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 - with: - gradle-home-cache-cleanup: true # Set environment variables - name: Export Properties @@ -73,8 +71,6 @@ jobs: echo "$CHANGELOG" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - ./gradlew listProductsReleases # prepare list of IDEs for Plugin Verifier - # Build plugin - name: Build plugin run: ./gradlew buildPlugin @@ -104,7 +100,7 @@ jobs: runs-on: ubuntu-latest steps: - # Check out current repository + # Check out the current repository - name: Fetch Sources uses: actions/checkout@v4 @@ -118,8 +114,6 @@ jobs: # Setup Gradle - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 - with: - gradle-home-cache-cleanup: true # Run tests - name: Run Tests @@ -158,7 +152,7 @@ jobs: tool-cache: false large-packages: false - # Check out current repository + # Check out the current repository - name: Fetch Sources uses: actions/checkout@v4 with: @@ -174,7 +168,7 @@ jobs: # Run Qodana inspections - name: Qodana - Code Inspection - uses: JetBrains/qodana-action@v2024.2.3 + uses: JetBrains/qodana-action@v2024.2 with: upload-result: true # upload results as github action artifacts cache-default-branch-only: true @@ -193,7 +187,7 @@ jobs: tool-cache: false large-packages: false - # Check out current repository + # Check out the current repository - name: Fetch Sources uses: actions/checkout@v4 @@ -207,8 +201,6 @@ jobs: # Setup Gradle - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 - with: - gradle-home-cache-cleanup: true # Cache Plugin Verifier IDEs - name: Setup Plugin Verifier IDEs Cache @@ -219,7 +211,7 @@ jobs: # Run Verify Plugin task and IntelliJ Plugin Verifier tool - name: Run Plugin Verification tasks - run: ./gradlew runPluginVerifier -Dplugin.verifier.home.dir=${{ needs.build.outputs.pluginVerifierHomeDir }} + run: ./gradlew verifyPlugin -Dplugin.verifier.home.dir=${{ needs.build.outputs.pluginVerifierHomeDir }} # Collect Plugin Verifier Result - name: Collect Plugin Verifier Result @@ -240,7 +232,7 @@ jobs: contents: write steps: - # Check out current repository + # Check out the current repository - name: Fetch Sources uses: actions/checkout@v4 @@ -264,4 +256,4 @@ jobs: --notes "$(cat << 'EOM' ${{ needs.build.outputs.changelog }} EOM - )" + )" \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a9dfda2b..c5176d2f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: pull-requests: write steps: - # Check out current repository + # Check out the current repository - name: Fetch Sources uses: actions/checkout@v4 with: @@ -34,8 +34,6 @@ jobs: # Setup Gradle - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 - with: - gradle-home-cache-cleanup: true # Set environment variables - name: Export Properties @@ -51,7 +49,7 @@ jobs: echo "$CHANGELOG" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - # Update Unreleased section with the current release note + # Update the Unreleased section with the current release note - name: Patch Changelog if: ${{ steps.properties.outputs.changelog != '' }} env: @@ -100,4 +98,4 @@ jobs: --title "Changelog update - \`$VERSION\`" \ --body "Current pull request contains patched \`CHANGELOG.md\` file for the \`$VERSION\` version." \ --label "$LABEL" \ - --head $BRANCH + --head $BRANCH \ No newline at end of file diff --git a/.github/workflows/run-ui-tests.yml b/.github/workflows/run-ui-tests.yml index a87e77a3..c15022d4 100644 --- a/.github/workflows/run-ui-tests.yml +++ b/.github/workflows/run-ui-tests.yml @@ -31,7 +31,7 @@ jobs: steps: - # Check out current repository + # Check out the current repository - name: Fetch Sources uses: actions/checkout@v4 @@ -45,8 +45,6 @@ jobs: # Setup Gradle - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 - with: - gradle-home-cache-cleanup: true # Run IDEA prepared for UI testing - name: Run IDE @@ -62,4 +60,4 @@ jobs: # Run tests - name: Tests - run: ./gradlew test + run: ./gradlew test \ No newline at end of file diff --git a/.github/workflows/template-cleanup.yml b/.github/workflows/template-cleanup.yml new file mode 100644 index 00000000..a104842f --- /dev/null +++ b/.github/workflows/template-cleanup.yml @@ -0,0 +1,80 @@ +# GitHub Actions Workflow responsible for cleaning up the IntelliJ Platform Plugin Template repository from the template-specific files and configurations. +# This workflow is supposed to be triggered automatically when a new template-based repository has been created. + +name: Template Cleanup +on: + push: + branches: [main] + +jobs: + + # Run a cleaning process only if the workflow is triggered by the non-"intellij-platform-plugin-template" repository. + template-cleanup: + name: Template Cleanup + runs-on: ubuntu-latest + if: github.event.repository.name != 'intellij-platform-plugin-template' + permissions: + contents: write + steps: + + # Check out the current repository + - name: Fetch Sources + uses: actions/checkout@v4 + + # Cleanup project + - name: Cleanup + run: | + export LC_CTYPE=C + export LANG=C + + # Prepare variables + NAME="${GITHUB_REPOSITORY##*/}" + ACTOR=$(echo $GITHUB_ACTOR | tr '[:upper:]' '[:lower:]') + SAFE_NAME=$(echo $NAME | sed 's/[^a-zA-Z0-9]//g' | tr '[:upper:]' '[:lower:]') + SAFE_ACTOR=$(echo $ACTOR | sed 's/[^a-zA-Z0-9]//g' | tr '[:upper:]' '[:lower:]') + GROUP="com.github.$SAFE_ACTOR.$SAFE_NAME" + + # Replace placeholders in the template-cleanup files + sed -i "s/%NAME%/$NAME/g" .github/template-cleanup/* + sed -i "s/%REPOSITORY%/${GITHUB_REPOSITORY/\//\\/}/g" .github/template-cleanup/* + sed -i "s/%GROUP%/$GROUP/g" .github/template-cleanup/* + + # Replace template package name in project files with $GROUP + find src -type f -exec sed -i "s/org.jetbrains.plugins.template/$GROUP/g" {} + + find src -type f -exec sed -i "s/IntelliJ Platform Plugin Template/$NAME/g" {} + + find src -type f -exec sed -i "s/JetBrains/$ACTOR/g" {} + + + # Move content + mkdir -p src/main/kotlin/${GROUP//.//} + mkdir -p src/test/kotlin/${GROUP//.//} + cp -R .github/template-cleanup/. . + cp -R src/main/kotlin/org/jetbrains/plugins/template/* src/main/kotlin/${GROUP//.//}/ + cp -R src/test/kotlin/org/jetbrains/plugins/template/* src/test/kotlin/${GROUP//.//}/ + + # Cleanup + rm -rf \ + .github/ISSUE_TEMPLATE \ + .github/readme \ + .github/template-cleanup \ + .github/workflows/template-cleanup.yml \ + .github/workflows/template-verify.yml \ + .idea/icon.png \ + src/main/kotlin/org \ + src/test/kotlin/org \ + CODE_OF_CONDUCT.md \ + LICENSE + + # Commit modified files + - name: Commit files + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add . + git commit -m "Template cleanup" + + # Push changes + - name: Push changes + uses: ad-m/github-push-action@master + with: + branch: main + github_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/template-verify.yml b/.github/workflows/template-verify.yml new file mode 100644 index 00000000..162820cc --- /dev/null +++ b/.github/workflows/template-verify.yml @@ -0,0 +1,43 @@ +# GitHub Actions Workflow verifies if the template repository is consistent with all provided content. + +name: Template Verify +on: + # Trigger the workflow on pushes to only the 'main' branch (this avoids duplicate checks being run e.g., for dependabot pull requests) + push: + branches: [main] + paths: ['**/gradle.properties'] + # Trigger the workflow on any pull request + pull_request: + paths: ['**/gradle.properties'] + +jobs: + + build: + name: Template Verify + if: github.event.repository.name == 'intellij-platform-plugin-template' + runs-on: ubuntu-latest + outputs: + version: ${{ steps.properties.outputs.version }} + changelog: ${{ steps.properties.outputs.changelog }} + steps: + + # Check out the current repository + - name: Fetch Sources + uses: actions/checkout@v4 + + # Compare `gradle.properties` with `.github/template-cleanup/gradle.properties` + - name: Verify gradle.properties + run: | + echo "\`\`\`diff" >> $GITHUB_STEP_SUMMARY + + diff -U 0 \ + -I '^pluginVersion' \ + -I '^pluginGroup' \ + -I '^pluginName' \ + -I '^pluginRepositoryUrl' \ + --label .github/template-cleanup/gradle.properties \ + --label gradle.properties \ + .github/template-cleanup/gradle.properties gradle.properties \ + >> $GITHUB_STEP_SUMMARY + + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 3aa13779..0a6cbb52 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,7 @@ import com.github.gradle.node.npm.task.NpmTask import org.jetbrains.changelog.Changelog import org.jetbrains.changelog.markdownToHTML +import org.jetbrains.intellij.platform.gradle.TestFrameworkType fun properties(key: String) = providers.gradleProperty(key) @@ -49,11 +50,30 @@ tasks.all { // Configure project's dependencies repositories { mavenCentral() + intellijPlatform { + defaultRepositories() + } } // Dependencies are managed with Gradle version catalog - read more: https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog dependencies { + testImplementation(libs.junit) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3") + intellijPlatform { + create(providers.gradleProperty("platformType"), providers.gradleProperty("platformVersion")) + + // Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins. + bundledPlugins(providers.gradleProperty("platformBundledPlugins").map { it.split(',') }) + + // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file for plugin from JetBrains Marketplace. + plugins(providers.gradleProperty("platformPlugins").map { it.split(',') }) + + instrumentationTools() + pluginVerifier() + zipSigner() + testFramework(TestFrameworkType.Platform) + } // implementation(libs.annotations) } @@ -63,13 +83,62 @@ kotlin { } // Configure Gradle IntelliJ Plugin - read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html -intellij { - pluginName = properties("pluginName") - version = properties("platformVersion") - type = properties("platformType") +// Configure IntelliJ Platform Gradle Plugin - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-extension.html +intellijPlatform { + pluginConfiguration { + version = providers.gradleProperty("pluginVersion") - // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file. - plugins = properties("platformPlugins").map { it.split(',').map(String::trim).filter(String::isNotEmpty) } + // Extract the section from README.md and provide for the plugin's manifest + description = providers.fileContents(layout.projectDirectory.file("README.md")).asText.map { + val start = "" + val end = "" + + with(it.lines()) { + if (!containsAll(listOf(start, end))) { + throw GradleException("Plugin description section not found in README.md:\n$start ... $end") + } + subList(indexOf(start) + 1, indexOf(end)).joinToString("\n").let(::markdownToHTML) + } + } + + val changelog = project.changelog // local variable for configuration cache compatibility + // Get the latest available change notes from the changelog file + changeNotes = providers.gradleProperty("pluginVersion").map { pluginVersion -> + with(changelog) { + renderItem( + (getOrNull(pluginVersion) ?: getUnreleased()) + .withHeader(false) + .withEmptySections(false), + Changelog.OutputType.HTML, + ) + } + } + + ideaVersion { + sinceBuild = providers.gradleProperty("pluginSinceBuild") + untilBuild = providers.gradleProperty("pluginUntilBuild") + } + } + + signing { + certificateChain = providers.environmentVariable("CERTIFICATE_CHAIN") + privateKey = providers.environmentVariable("PRIVATE_KEY") + password = providers.environmentVariable("PRIVATE_KEY_PASSWORD") + } + + publishing { + token = providers.environmentVariable("PUBLISH_TOKEN") + // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 + // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: + // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel + channels = providers.gradleProperty("pluginVersion").map { listOf(it.substringAfter('-', "").substringBefore('.').ifEmpty { "default" }) } + } + + pluginVerification { + ides { + recommended() + } + } } // Configure Gradle Changelog Plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin @@ -94,61 +163,28 @@ tasks { gradleVersion = properties("gradleVersion").get() } - patchPluginXml { - version = properties("pluginVersion") - sinceBuild = properties("pluginSinceBuild") - untilBuild = properties("pluginUntilBuild") - - // Extract the section from README.md and provide for the plugin's manifest - pluginDescription = - providers.fileContents(layout.projectDirectory.file("README.md")).asText.map { - val start = "" - val end = "" - - with(it.lines()) { - if (!containsAll(listOf(start, end))) { - throw GradleException("Plugin description section not found in README.md:\n$start ... $end") - } - subList(indexOf(start) + 1, indexOf(end)).joinToString("\n").let(::markdownToHTML) - } - } + publishPlugin { + dependsOn(patchChangelog) + } +} - val changelog = project.changelog // local variable for configuration cache compatibility - // Get the latest available change notes from the changelog file - changeNotes = - properties("pluginVersion").map { pluginVersion -> - with(changelog) { - renderItem( - (getOrNull(pluginVersion) ?: getUnreleased()) - .withHeader(false) - .withEmptySections(false), - Changelog.OutputType.HTML, +intellijPlatformTesting { + runIde { + register("runIdeForUiTests") { + task { + jvmArgumentProviders += CommandLineArgumentProvider { + listOf( + "-Drobot-server.port=8082", + "-Dide.mac.message.dialogs.as.sheets=false", + "-Djb.privacy.policy.text=", + "-Djb.consents.confirmation.enabled=false", ) } } - } - - // Configure UI tests plugin - // Read more: https://github.com/JetBrains/intellij-ui-test-robot - runIdeForUiTests { - systemProperty("robot-server.port", "8082") - systemProperty("ide.mac.message.dialogs.as.sheets", "false") - systemProperty("jb.privacy.policy.text", "") - systemProperty("jb.consents.confirmation.enabled", "false") - } - - signPlugin { - certificateChain = environment("CERTIFICATE_CHAIN") - privateKey = environment("PRIVATE_KEY") - password = environment("PRIVATE_KEY_PASSWORD") - } - publishPlugin { - dependsOn("patchChangelog") - token = environment("PUBLISH_TOKEN") - // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 - // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: - // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel - channels = properties("pluginVersion").map { listOf(it.substringAfter('-', "").substringBefore('.').ifEmpty { "default" }) } + plugins { + robotServerPlugin() + } + } } } diff --git a/gradle.properties b/gradle.properties index 168edda8..dc2d7b2c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ pluginGroup = com.github.ramonvermeulen.dbtToolkit pluginName = dbt-toolkit pluginRepositoryUrl = https://github.com/ramonvermeulen/dbt-toolkit # SemVer format -> https://semver.org -pluginVersion = 0.1.3 +pluginVersion = 0.2.0 # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html pluginSinceBuild = 233 @@ -12,14 +12,16 @@ pluginUntilBuild = 243.* # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension platformType = IC -platformVersion = 2023.3.7 +platformVersion = 2023.3.8 # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html # Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 platformPlugins = PythonCore:233.13135.103 +# Example: platformBundledPlugins = com.intellij.java +platformBundledPlugins = # Gradle Releases -> https://github.com/gradle/gradle/releases -gradleVersion = 8.7 +gradleVersion = 8.10.2 # Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib kotlin.stdlib.default.dependency = false @@ -28,4 +30,4 @@ kotlin.stdlib.default.dependency = false org.gradle.configuration-cache = true # Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html -org.gradle.caching = true +org.gradle.caching = true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e505fd6b..daa58817 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,20 +1,22 @@ [versions] # libraries +junit = "4.13.2" annotations = "26.0.1" # plugins kotlin = "2.0.21" changelog = "2.2.1" -gradleIntelliJPlugin = "1.17.4" +gradleIntelliJPlugin = "2.1.0" qodana = "2024.2.3" kover = "0.8.3" [libraries] +junit = { group = "junit", name = "junit", version.ref = "junit" } annotations = { group = "org.jetbrains", name = "annotations", version.ref = "annotations" } [plugins] changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } -gradleIntelliJPlugin = { id = "org.jetbrains.intellij", version.ref = "gradleIntelliJPlugin" } +gradleIntelliJPlugin = { id = "org.jetbrains.intellij.platform", version.ref = "gradleIntelliJPlugin" } kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } qodana = { id = "org.jetbrains.qodana", version.ref = "qodana" } diff --git a/lineage-panel/src/index.css b/lineage-panel/src/index.css index c13206fe..07cd7203 100644 --- a/lineage-panel/src/index.css +++ b/lineage-panel/src/index.css @@ -12,21 +12,22 @@ body, margin: 0; } -@keyframes rotateAndGrow { - 1% { - transform: scale(1.35) rotate(-5deg); +@keyframes background-animation { + 0% { + background-position: 0% 50%; } 100% { - transform: scale(1) rotate(0); + background-position: 200% 50%; } } .active { - animation: rotateAndGrow 0.6s cubic-bezier(0.68, -0.55, 0.27, 1.55); + animation: background-animation 15s linear infinite; box-shadow: 0 0 20px rgba(0, 0, 0, 0.2); font-weight: bold; border: 0; - background: linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%); + background: linear-gradient(90deg, #FE6B8B, #FF8E53, #FE6B8B, #FF8E53, #FE6B8B); + background-size: 300% 300%; color: white; text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2); } diff --git a/settings.gradle.kts b/settings.gradle.kts index d4abb693..7133db43 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,4 +2,4 @@ plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } -rootProject.name = "dbt-idea" +rootProject.name = "dbt-toolkit" diff --git a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/services/DbtToolkitSettingsService.kt b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/services/DbtToolkitSettingsService.kt index d5f1d24a..369ea86a 100644 --- a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/services/DbtToolkitSettingsService.kt +++ b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/services/DbtToolkitSettingsService.kt @@ -21,7 +21,7 @@ class DbtToolkitSettingsService : PersistentStateComponent = mapOf(), - var settingsDbtCommandTimeout: Long = 120, + var settingsDbtCommandTimeout: Int = 120, var dbtProjectsDir: String = "", var dbtTargetDir: String = "", var dbtProject: Map = mapOf(), @@ -30,7 +30,8 @@ class DbtToolkitSettingsService : PersistentStateComponent = listOf(), var dbtMacroPaths: List = listOf(), var dbtProjectName: String = "", - var dbtVersion: Pair? = null, + var dbtVersionMajor: Int? = null, + var dbtVersionMinor: Int? = null, ) private var state = State() diff --git a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/services/ManifestService.kt b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/services/ManifestService.kt index 49c41871..8be95dab 100644 --- a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/services/ManifestService.kt +++ b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/services/ManifestService.kt @@ -42,7 +42,11 @@ class ManifestService(project: Project) { if (file.exists()) { manifest = JsonParser.parseString(file.readText()).asJsonObject val dbtVersionString = manifest!!.getAsJsonObject("metadata").get("dbt_version").asString - settingsService.state.dbtVersion = extractMajorMinor(dbtVersionString) + val majorMinor = extractMajorMinor(dbtVersionString) + if (majorMinor != null) { + settingsService.state.dbtVersionMajor = majorMinor.first + settingsService.state.dbtVersionMinor = majorMinor.second + } } else { println("Manifest file does not exist") println("looked in the following path: ${settingsService.state.settingsDbtTargetDir}/manifest.json") diff --git a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/services/ProcessOutputHandlerService.kt b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/services/ProcessOutputHandlerService.kt index c9ed6de4..fd109250 100644 --- a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/services/ProcessOutputHandlerService.kt +++ b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/services/ProcessOutputHandlerService.kt @@ -16,7 +16,7 @@ class ProcessOutputHandlerService(project: Project) { fun handleOutput(process: Process): Pair { val exitCode = - if (process.waitFor(settings.state.settingsDbtCommandTimeout, TimeUnit.SECONDS)) { + if (process.waitFor(settings.state.settingsDbtCommandTimeout.toLong(), TimeUnit.SECONDS)) { process.exitValue() } else { process.destroy() diff --git a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/DbtToolkitMainToolWindow.kt b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/DbtToolkitMainToolWindow.kt index 29257583..6df72c85 100644 --- a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/DbtToolkitMainToolWindow.kt +++ b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/DbtToolkitMainToolWindow.kt @@ -1,8 +1,8 @@ package com.github.ramonvermeulen.dbtToolkit.ui import com.github.ramonvermeulen.dbtToolkit.services.DbtToolkitSettingsService -import com.github.ramonvermeulen.dbtToolkit.ui.console.ConsoleOutputPanel import com.github.ramonvermeulen.dbtToolkit.ui.panels.CompiledSqlPanel +import com.github.ramonvermeulen.dbtToolkit.ui.panels.ConsoleOutputPanel import com.github.ramonvermeulen.dbtToolkit.ui.panels.DocsPanel import com.github.ramonvermeulen.dbtToolkit.ui.panels.LineagePanel import com.github.ramonvermeulen.dbtToolkit.ui.panels.PreviewDataPanel diff --git a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/CompiledSqlPanel.kt b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/CompiledSqlPanel.kt index 819b7373..d1cd7e96 100644 --- a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/CompiledSqlPanel.kt +++ b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/CompiledSqlPanel.kt @@ -13,6 +13,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.fileTypes.FileTypeManager import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Disposer import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileManager import java.awt.BorderLayout @@ -28,12 +29,11 @@ class CompiledSqlPanel(project: Project) : IdeaPanel, Disposable, ActiveFileList private val mainPanel = JPanel(BorderLayout()) private val recompileButton = JButton("Re-compile model") private var document = EditorFactory.getInstance().createDocument("") + private val editor = EditorFactory.getInstance().createEditor(document, project, FileTypeManager.getInstance().getFileTypeByExtension("sql"), true) private var activeFile: VirtualFile? = null init { - project.messageBus.connect().subscribe(ActiveFileService.TOPIC, this) - val fileType = FileTypeManager.getInstance().getFileTypeByExtension("sql") - val editor = EditorFactory.getInstance().createEditor(document, project, fileType, true) + project.messageBus.connect(project).subscribe(ActiveFileService.TOPIC, this) val editorTextField = editor.component // to set the initial file, since the subscription is only set-up after // opening the panel (lazy) for the first time @@ -41,6 +41,7 @@ class CompiledSqlPanel(project: Project) : IdeaPanel, Disposable, ActiveFileList recompileButton.addActionListener { handleRecompileButtonClick() } mainPanel.add(recompileButton, BorderLayout.NORTH) mainPanel.add(editorTextField, BorderLayout.CENTER) + Disposer.register(project, this) } private fun handleRecompileButtonClick() { @@ -59,7 +60,7 @@ class CompiledSqlPanel(project: Project) : IdeaPanel, Disposable, ActiveFileList } } } - val command = if (settings.state.dbtVersion != null && settings.state.dbtVersion!!.first <= 1 && settings.state.dbtVersion!!.second < 5) { + val command = if (settings.state.dbtVersionMajor != null && settings.state.dbtVersionMinor != null && settings.state.dbtVersionMajor!! <= 1 && settings.state.dbtVersionMinor!! < 5) { // --no-populate-cache is only available in dbt >= 1.5 listOf("compile", "--select", activeFile!!.nameWithoutExtension) } else { @@ -135,6 +136,7 @@ class CompiledSqlPanel(project: Project) : IdeaPanel, Disposable, ActiveFileList } override fun dispose() { - // Implement your dispose logic here + EditorFactory.getInstance().releaseEditor(editor) + mainPanel.removeAll() } } diff --git a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/console/ConsoleOutputPanel.kt b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/ConsoleOutputPanel.kt similarity index 81% rename from src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/console/ConsoleOutputPanel.kt rename to src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/ConsoleOutputPanel.kt index 449541a9..52037390 100644 --- a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/console/ConsoleOutputPanel.kt +++ b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/ConsoleOutputPanel.kt @@ -1,4 +1,4 @@ -package com.github.ramonvermeulen.dbtToolkit.ui.console +package com.github.ramonvermeulen.dbtToolkit.ui.panels import com.github.ramonvermeulen.dbtToolkit.services.LoggingEvent import com.github.ramonvermeulen.dbtToolkit.services.LoggingListener @@ -8,6 +8,7 @@ import com.intellij.execution.impl.ConsoleViewImpl import com.intellij.execution.ui.ConsoleView import com.intellij.openapi.Disposable import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Disposer import java.awt.BorderLayout import javax.swing.JComponent import javax.swing.JPanel @@ -16,12 +17,14 @@ import javax.swing.SwingUtilities class ConsoleOutputPanel(project: Project) : IdeaPanel, Disposable, LoggingListener { private val mainPanel: JPanel = JPanel(BorderLayout()) private val consoleView: ConsoleView = ConsoleViewImpl(project, false) + private val connection = project.messageBus.connect(project) init { - project.messageBus.connect().subscribe(LoggingService.TOPIC, this) + connection.subscribe(LoggingService.TOPIC, this) SwingUtilities.invokeLater { mainPanel.add(consoleView.component, BorderLayout.CENTER) } + Disposer.register(project, this) } override fun getContent(): JComponent { @@ -41,8 +44,6 @@ class ConsoleOutputPanel(project: Project) : IdeaPanel, Disposable, LoggingListe } override fun dispose() { - SwingUtilities.invokeLater { - consoleView.dispose() - } + consoleView.dispose() } } diff --git a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/DocsPanel.kt b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/DocsPanel.kt index e462fbb3..6edcc4a5 100644 --- a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/DocsPanel.kt +++ b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/DocsPanel.kt @@ -13,6 +13,7 @@ import com.intellij.openapi.Disposable import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.service import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Disposer import com.intellij.ui.jcef.JBCefApp import com.intellij.ui.jcef.JBCefBrowser import com.intellij.ui.jcef.JBCefBrowserBuilder @@ -71,6 +72,7 @@ class DocsPanel(project: Project) : IdeaPanel, Disposable { mainPanel.add(buttonPanel) mainPanel.add(browser.component) } + Disposer.register(project, this) } private fun handleRegenerateButtonClick() { @@ -132,6 +134,8 @@ class DocsPanel(project: Project) : IdeaPanel, Disposable { } override fun dispose() { - TODO("Not yet implemented") + browser.jbCefClient.dispose() + browser.dispose() + mainPanel.removeAll() } } diff --git a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/LineagePanel.kt b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/LineagePanel.kt index 385a2c96..a1f76fe7 100644 --- a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/LineagePanel.kt +++ b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/LineagePanel.kt @@ -23,6 +23,7 @@ import com.intellij.openapi.application.ModalityState import com.intellij.openapi.components.service import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.removeUserData import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileManager @@ -59,7 +60,7 @@ class LineagePanel(private val project: Project) : private val settings = project.service() private val ourCefClient = JBCefApp.getInstance().createClient() private val isDebug = System.getProperty("idea.plugin.in.sandbox.mode") == "true" - private val browser: JBCefBrowser = JBCefBrowserBuilder().setClient(ourCefClient).setEnableOpenDevToolsMenuItem(isDebug).setOffScreenRendering(true).build() + private val browser: JBCefBrowser = JBCefBrowserBuilder().setClient(ourCefClient).setEnableOpenDevToolsMenuItem(isDebug).setOffScreenRendering(false).build() private val javaScriptEngineProxy: JBCefJSQuery = JBCefJSQuery.create(browser as JBCefBrowserBase) private val mainPanel = JPanel(BorderLayout()) private var lineageInfo: LineageInfo? = null @@ -67,8 +68,8 @@ class LineagePanel(private val project: Project) : private var isRefreshingLineage = false init { - project.messageBus.connect().subscribe(ActiveFileService.TOPIC, this) - project.messageBus.connect().subscribe(LineageInfoService.TOPIC, this) + project.messageBus.connect(project).subscribe(ActiveFileService.TOPIC, this) + project.messageBus.connect(project).subscribe(LineageInfoService.TOPIC, this) ApplicationManager.getApplication().executeOnPooledThread { initiateCefRequestHandler() SwingUtilities.invokeLater { @@ -82,6 +83,7 @@ class LineagePanel(private val project: Project) : browser.loadURL("lineage-panel-dist/${LINEAGE_PANEL_INDEX}") } } + Disposer.register(project, this) } private fun handleJavaScriptCallback(result: String): JBCefJSQuery.Response? { @@ -263,5 +265,10 @@ class LineagePanel(private val project: Project) : } override fun dispose() { + project.messageBus.dispose() + javaScriptEngineProxy.dispose() + browser.jbCefClient.dispose() + browser.dispose() + mainPanel.removeAll() } } diff --git a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/PreviewDataPanel.kt b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/PreviewDataPanel.kt index 69c9353d..fc3e2234 100644 --- a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/PreviewDataPanel.kt +++ b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/panels/PreviewDataPanel.kt @@ -13,6 +13,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.fileTypes.FileTypeManager import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Disposer import com.intellij.openapi.vfs.VirtualFile import java.awt.BorderLayout import javax.swing.JButton @@ -26,12 +27,11 @@ class PreviewDataPanel(project: Project) : IdeaPanel, Disposable, ActiveFileList private val mainPanel = JPanel(BorderLayout()) private val previewDataButton = JButton("Preview Data") private var document = EditorFactory.getInstance().createDocument("") + private val editor = EditorFactory.getInstance().createEditor(document, project, FileTypeManager.getInstance().getFileTypeByExtension("txt"), true) private var activeFile: VirtualFile? = null init { - project.messageBus.connect().subscribe(ActiveFileService.TOPIC, this) - val fileType = FileTypeManager.getInstance().getFileTypeByExtension("txt") - val editor = EditorFactory.getInstance().createEditor(document, project, fileType, true) + project.messageBus.connect(project).subscribe(ActiveFileService.TOPIC, this) val editorTextField = editor.component // to set the initial file, since the subscription is only set-up after // opening the panel (lazy) for the first time @@ -39,6 +39,7 @@ class PreviewDataPanel(project: Project) : IdeaPanel, Disposable, ActiveFileList previewDataButton.addActionListener { handleRecompileButtonClick() } mainPanel.add(previewDataButton, BorderLayout.NORTH) mainPanel.add(editorTextField, BorderLayout.CENTER) + Disposer.register(project, this) } private fun handleRecompileButtonClick() { @@ -84,7 +85,7 @@ class PreviewDataPanel(project: Project) : IdeaPanel, Disposable, ActiveFileList private fun previewData() { ApplicationManager.getApplication().executeOnPooledThread { - val command = if (settings.state.dbtVersion != null && settings.state.dbtVersion!!.first <= 1 && settings.state.dbtVersion!!.second < 5) { + val command = if (settings.state.dbtVersionMajor != null && settings.state.dbtVersionMinor != null && settings.state.dbtVersionMajor!! <= 1 && settings.state.dbtVersionMinor!! < 5) { // --no-populate-cache is only available in dbt >= 1.5 listOf("show", "--select", activeFile!!.nameWithoutExtension, "--limit", "10") } else { @@ -120,6 +121,7 @@ class PreviewDataPanel(project: Project) : IdeaPanel, Disposable, ActiveFileList } override fun dispose() { - // Implement your dispose logic here + EditorFactory.getInstance().releaseEditor(editor) + mainPanel.removeAll() } } diff --git a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/settings/DbtToolkitSettingsConfigurable.kt b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/settings/DbtToolkitSettingsConfigurable.kt index 2dcd5af7..077005b9 100644 --- a/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/settings/DbtToolkitSettingsConfigurable.kt +++ b/src/main/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/settings/DbtToolkitSettingsConfigurable.kt @@ -5,6 +5,7 @@ import com.intellij.openapi.components.service import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory import com.intellij.openapi.options.Configurable import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.TextBrowseFolderListener import com.intellij.openapi.ui.TextFieldWithBrowseButton import com.intellij.ui.JBIntSpinner import com.intellij.ui.table.JBTable @@ -23,7 +24,7 @@ import javax.swing.JScrollPane import javax.swing.table.DefaultTableModel class DbtToolkitSettingsConfigurable(project: Project) : Configurable { - private var dbtToolkitSettingsService = project.service() + private var state = project.service().state private var dbtProjectDirField = TextFieldWithBrowseButton() private var dbtTargetDirField = TextFieldWithBrowseButton() private var dotEnvFilePathField = TextFieldWithBrowseButton() @@ -33,22 +34,24 @@ class DbtToolkitSettingsConfigurable(project: Project) : Configurable { init { dbtProjectDirField.addBrowseFolderListener( - "Select dbt Project Directory", - null, - project, - FileChooserDescriptorFactory.createSingleFolderDescriptor(), + TextBrowseFolderListener( + FileChooserDescriptorFactory.createSingleFolderDescriptor(), + project, + ), ) + dbtTargetDirField.addBrowseFolderListener( - "Select dbt Target Directory", - null, - project, - FileChooserDescriptorFactory.createSingleFolderDescriptor(), + TextBrowseFolderListener( + FileChooserDescriptorFactory.createSingleFolderDescriptor(), + project, + ), ) + dotEnvFilePathField.addBrowseFolderListener( - "Select .env File", - null, - project, - FileChooserDescriptorFactory.createSingleFileDescriptor(), + TextBrowseFolderListener( + FileChooserDescriptorFactory.createSingleFileDescriptor(), + project, + ), ) } @@ -123,7 +126,7 @@ class DbtToolkitSettingsConfigurable(project: Project) : Configurable { add(removeButton) } - dbtToolkitSettingsService.state.settingsEnvVars.forEach { (name, value) -> + state.settingsEnvVars.forEach { (name, value) -> (envVarsTable.model as DefaultTableModel).addRow(arrayOf(name, value)) } @@ -135,21 +138,29 @@ class DbtToolkitSettingsConfigurable(project: Project) : Configurable { } override fun reset() { - dbtProjectDirField.text = dbtToolkitSettingsService.state.settingsDbtProjectDir - dbtTargetDirField.text = dbtToolkitSettingsService.state.settingsDbtTargetDir - dbtCommandTimeoutField.value = dbtToolkitSettingsService.state.settingsDbtCommandTimeout - dotEnvFilePathField.text = dbtToolkitSettingsService.state.settingsDotEnvFilePath - - while (envVarsTable.model.rowCount > 0) { - (envVarsTable.model as DefaultTableModel).removeRow(0) + dbtProjectDirField.text = state.settingsDbtProjectDir + dbtTargetDirField.text = state.settingsDbtTargetDir + dbtCommandTimeoutField.value = state.settingsDbtCommandTimeout + dotEnvFilePathField.text = state.settingsDotEnvFilePath + + // Clear existing rows + val model = envVarsTable.model as DefaultTableModel + model.rowCount = 0 + + // Populate the table with environment variables + state.settingsEnvVars.forEach { (name, value) -> + model.addRow(arrayOf(name, value)) } + + // Notify the table that the data has changed + model.fireTableDataChanged() } private fun getConfiguredEnvVars(): MutableMap { val envVars = mutableMapOf() for (i in 0 until envVarsTable.model.rowCount) { val name = envVarsTable.model.getValueAt(i, 0) as String - val value = envVarsTable.model.getValueAt(i, 1) as String + val value = envVarsTable.model.getValueAt(i, 1) as String // is empty envVars[name] = value } return envVars @@ -158,21 +169,21 @@ class DbtToolkitSettingsConfigurable(project: Project) : Configurable { override fun isModified(): Boolean { val envVars = getConfiguredEnvVars() - return dbtProjectDirField.text != dbtToolkitSettingsService.state.settingsDbtProjectDir || - dbtTargetDirField.text != dbtToolkitSettingsService.state.settingsDbtTargetDir || - dbtCommandTimeoutField.value != dbtToolkitSettingsService.state.settingsDbtCommandTimeout || - envVars != dbtToolkitSettingsService.state.settingsEnvVars || - dotEnvFilePathField.text != dbtToolkitSettingsService.state.settingsDotEnvFilePath + return dbtProjectDirField.text != state.settingsDbtProjectDir || + dbtTargetDirField.text != state.settingsDbtTargetDir || + dbtCommandTimeoutField.value != state.settingsDbtCommandTimeout || + envVars != state.settingsEnvVars || + dotEnvFilePathField.text != state.settingsDotEnvFilePath } override fun apply() { val envVars = getConfiguredEnvVars() - dbtToolkitSettingsService.state.settingsDbtProjectDir = dbtProjectDirField.text - dbtToolkitSettingsService.state.settingsDbtTargetDir = dbtTargetDirField.text - dbtToolkitSettingsService.state.settingsDbtCommandTimeout = dbtCommandTimeoutField.value as Long - dbtToolkitSettingsService.state.settingsEnvVars = envVars - dbtToolkitSettingsService.state.settingsDotEnvFilePath = dotEnvFilePathField.text + state.settingsDbtProjectDir = dbtProjectDirField.text + state.settingsDbtTargetDir = dbtTargetDirField.text + state.settingsDbtCommandTimeout = dbtCommandTimeoutField.value as Int + state.settingsEnvVars = envVars + state.settingsDotEnvFilePath = dotEnvFilePathField.text } override fun disposeUIResources() { diff --git a/src/test/kotlin/com/github/ramonvermeulen/dbtToolkit/services/DbtToolkitSettingsServiceTest.kt b/src/test/kotlin/com/github/ramonvermeulen/dbtToolkit/services/DbtToolkitSettingsServiceTest.kt new file mode 100644 index 00000000..5e15ffbf --- /dev/null +++ b/src/test/kotlin/com/github/ramonvermeulen/dbtToolkit/services/DbtToolkitSettingsServiceTest.kt @@ -0,0 +1,42 @@ +package com.github.ramonvermeulen.dbtToolkit.services + +import com.intellij.openapi.components.service +import com.intellij.testFramework.LightPlatformTestCase +import junit.framework.TestCase + +class DbtToolkitSettingsServiceTest : LightPlatformTestCase() { + private lateinit var settingsService: DbtToolkitSettingsService + + public override fun setUp() { + super.setUp() + settingsService = project.service() + settingsService.loadState(DbtToolkitSettingsService.State()) + } + + public override fun tearDown() { + try { + settingsService.loadState(DbtToolkitSettingsService.State()) + } finally { + super.tearDown() + } + } + + fun `test default state`() { + val state = settingsService.state + TestCase.assertNotNull(state) + TestCase.assertEquals(state.settingsDbtProjectDir, DbtToolkitSettingsService.State().settingsDbtTargetDir) + TestCase.assertEquals(state.settingsDotEnvFilePath, DbtToolkitSettingsService.State().settingsDotEnvFilePath) + } + + fun `test update state`() { + val newState = DbtToolkitSettingsService.State().apply { + settingsDbtProjectDir = "new project dir" + settingsDotEnvFilePath = "new dotenv path" + } + settingsService.loadState(newState) + + val state = settingsService.state + TestCase.assertEquals("new project dir", state.settingsDbtProjectDir) + TestCase.assertEquals("new dotenv path", state.settingsDotEnvFilePath) + } +} diff --git a/src/test/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/settings/DbtToolkitSettingsConfigurableTest.kt b/src/test/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/settings/DbtToolkitSettingsConfigurableTest.kt index 719a47c5..23dd5d75 100644 --- a/src/test/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/settings/DbtToolkitSettingsConfigurableTest.kt +++ b/src/test/kotlin/com/github/ramonvermeulen/dbtToolkit/ui/settings/DbtToolkitSettingsConfigurableTest.kt @@ -8,20 +8,23 @@ import junit.framework.TestCase import javax.swing.JComponent import javax.swing.JPanel -// TODO(ramon) for UI tests, take a lookt at https://github.com/JetBrains/intellij-ui-test-robot class DbtToolkitSettingsConfigurableTest : LightPlatformTestCase() { private lateinit var mainSwingComponent: JComponent private lateinit var configurable: DbtToolkitSettingsConfigurable - private lateinit var settingsService: DbtToolkitSettingsService public override fun setUp() { super.setUp() configurable = DbtToolkitSettingsConfigurable(project) - // see component lifecycle: https://plugins.jetbrains.com/docs/intellij/settings-guide.html#intellij-platform-interactions-with-configurable mainSwingComponent = configurable.createComponent() configurable.reset() - settingsService = project.service() - settingsService.loadState(DbtToolkitSettingsService.State()) + } + + public override fun tearDown() { + try { + project.service().loadState(DbtToolkitSettingsService.State()) + } finally { + super.tearDown() + } } fun `test isModified no modifications`() { @@ -37,12 +40,32 @@ class DbtToolkitSettingsConfigurableTest : LightPlatformTestCase() { } fun `test apply`() { + val settingsService = project.service() + val dbtProjectsDirField = (mainSwingComponent.getComponent(0) as JPanel).getComponent(1) as TextFieldWithBrowseButton dbtProjectsDirField.text = "some text" val dbtDotEnvDirField = (mainSwingComponent.getComponent(0) as JPanel).getComponent(5) as TextFieldWithBrowseButton dbtDotEnvDirField.text = "/foo/bar" configurable.apply() + TestCase.assertEquals("some text", settingsService.state.settingsDbtProjectDir) TestCase.assertEquals("/foo/bar", settingsService.state.settingsDotEnvFilePath) } + + fun `test reset`() { + val settingsService = project.service() + + settingsService.state.settingsDbtProjectDir = "initial project dir" + settingsService.state.settingsDotEnvFilePath = "initial dotenv path" + configurable.reset() + + val dbtProjectsDirField = (mainSwingComponent.getComponent(0) as JPanel).getComponent(1) as TextFieldWithBrowseButton + dbtProjectsDirField.text = "modified project dir" + val dbtDotEnvDirField = (mainSwingComponent.getComponent(0) as JPanel).getComponent(5) as TextFieldWithBrowseButton + dbtDotEnvDirField.text = "modified dotenv path" + + configurable.reset() + TestCase.assertEquals("initial project dir", dbtProjectsDirField.text) + TestCase.assertEquals("initial dotenv path", dbtDotEnvDirField.text) + } }