diff --git a/.gitignore b/.gitignore
index ede5725..e950034 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,13 +6,7 @@ build/
!**/src/test/**/build/
### IntelliJ IDEA ###
-.idea/modules.xml
-.idea/jarRepositories.xml
-.idea/compiler.xml
-.idea/libraries/
-.idea/dataSources/
-.idea/dataSources.local.xml
-.idea/dataSources.xml
+.idea/
*.iws
*.iml
*.ipr
diff --git a/.idea/sonarlint.xml b/.idea/sonarlint.xml
deleted file mode 100644
index cfb6719..0000000
--- a/.idea/sonarlint.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index b8104bf..1cccea4 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -103,7 +103,7 @@ repositories {
}
dependencies {
- implementation("org.itsallcode.openfasttrace:openfasttrace:4.5.0")
+ implementation("org.itsallcode.openfasttrace:openfasttrace:4.8.0")
intellijPlatform {
intellijIdea("2026.1.3")
diff --git a/doc/changes/changelog.md b/doc/changes/changelog.md
index 8a469c7..04622c2 100644
--- a/doc/changes/changelog.md
+++ b/doc/changes/changelog.md
@@ -1,5 +1,6 @@
# Changelog
+* [0.10.0](changes_0.10.0.md)
* [0.9.0](changes_0.9.0.md)
* [0.8.1](changes_0.8.1.md)
* [0.8.0](changes_0.8.0.md)
diff --git a/doc/changes/changes_0.10.0.md b/doc/changes/changes_0.10.0.md
new file mode 100644
index 0000000..fe87add
--- /dev/null
+++ b/doc/changes/changes_0.10.0.md
@@ -0,0 +1,11 @@
+# OpenFastTrace IntelliJ Plugin 0.10.0, released 2026-07-04
+
+We also updated the bundled OFT to 4.8.0 so tag filters now work end to end instead of being ignored.
+
+## Bundled OpenFastTrace
+
+OpenFastTrace 4.8.0
+
+## Bugfix
+
+* #39: Re-enabled tag filter test
\ No newline at end of file
diff --git a/doc/changesets/22-bundle-live-templates.md b/doc/changesets/22-bundle-live-templates.md
index dfa1b97..09fb296 100644
--- a/doc/changesets/22-bundle-live-templates.md
+++ b/doc/changesets/22-bundle-live-templates.md
@@ -52,7 +52,7 @@ The plugin should package one repository-owned OFT live-template definition file
- [x] Copy the existing OFT live-template XML from `openfasttrace-ide-templates` into a plugin-owned resource location under `src/main/resources`
- [x] Add the missing OFT scenario live template to the bundled XML and keep the naming, placeholders, and OFT notation aligned with the existing template set
-- [x] Register the bundled live-template resource in [plugin.xml](/home/seb/git/openfasttrace-intellij-plugin/src/main/resources/META-INF/plugin.xml)
+- [x] Register the bundled live-template resource in `plugin`.
- [x] Confirm the Gradle plugin packaging includes the live-template resource in the built plugin artifact without introducing new dependencies
### Automated Verification
diff --git a/doc/changesets/24-auto-completion-for-covers-section.md b/doc/changesets/24-auto-completion-for-covers-section.md
index bc06130..930b442 100644
--- a/doc/changesets/24-auto-completion-for-covers-section.md
+++ b/doc/changesets/24-auto-completion-for-covers-section.md
@@ -58,7 +58,7 @@ Ranking should be deterministic and acceptance-criteria-driven. The implementati
- [x] Implement deterministic ranking that prioritizes exact full-ID prefix matches over name-prefix matches, name-substring matches, and artifact-type prefix matches
- [x] Define stable tie-breakers for equally ranked matches so completion results stay predictable across runs and files
- [x] Keep completion suggestions limited to declared specification items and exclude coverage occurrences or synthetic non-declaration matches
-- [x] Register the completion extension in [plugin.xml](/home/seb/git/openfasttrace-intellij-plugin/src/main/resources/META-INF/plugin.xml) without adding new dependencies
+- [x] Register the completion extension in `plugin.xml` without adding new dependencies
- [x] Evaluate whether IntelliJ's normal popup behavior already satisfies the optional "next best matches near the input point" acceptance criterion and only add extra logic if a concrete gap remains
### Automated Verification
diff --git a/doc/changesets/39-re-enable-disabled-tag-filter-test.md b/doc/changesets/39-re-enable-disabled-tag-filter-test.md
new file mode 100644
index 0000000..eb9934e
--- /dev/null
+++ b/doc/changesets/39-re-enable-disabled-tag-filter-test.md
@@ -0,0 +1,52 @@
+# GH-39 Re-enable disabled tag filter test
+
+## Goal
+
+Re-enable the disabled tag-filter regression test in `OftTraceServiceTest` now that OpenFastTrace 4.8.0 includes the upstream tag-parser fix. The plugin should once again verify that tag filtering works end to end for traced Markdown content.
+
+## Scope
+
+In scope:
+
+* Update the bundled OpenFastTrace dependency from 4.5.0 to 4.8.0 so the plugin exercises the fixed upstream tag parser.
+* Remove the temporary `@Disabled` suppression from `testGivenTagFilterMatchingArtifactWhenTracingThenItIncludesTheArtifact`.
+* Keep the existing tag-filter behavior and test intent unchanged.
+* Verify the fix with focused tests and the normal project quality gates.
+
+Out of scope:
+
+* Adding a new user-facing tag-filter feature.
+* Changing requirement or design text, because the current specification already covers tag filtering.
+* Broadening trace filter semantics beyond the current comma-separated filter model.
+
+## Design References
+
+* [System Requirements](../system_requirements.md)
+* [Quality Requirements](../design/quality_requirements.md)
+* [Runtime View](../design/runtime_view.md)
+* [Building Block View](../design/building_block_view.md)
+
+## Strategy
+
+Treat this as an upstream dependency alignment issue rather than a product feature change. Move the project to OpenFastTrace 4.8.0, drop the temporary test suppression, and confirm that the existing trace service still passes tag filters through to the library.
+
+## Task List
+
+- [ ] Create and checkout a new Git branch `fix/39-re-enable-disabled-tag-filter-test`
+
+### Requirements And Design
+
+- [x] Confirm that the existing `req~filter-trace-by-tags~1` and `scn~filter-run-configuration-by-tags~1` coverage already describes the intended behavior, so no requirement or design edits are needed.
+
+### Implementation
+
+- [x] Update the bundled OpenFastTrace dependency to 4.8.0 in `build.gradle.kts` and refresh `gradle.lockfile` as needed.
+- [x] Remove the `@Disabled` annotation from `testGivenTagFilterMatchingArtifactWhenTracingThenItIncludesTheArtifact`.
+- [x] Keep the tag-filter regression test focused on the existing Markdown-based end-to-end trace flow.
+
+### Verification
+
+- [x] Run the focused `OftTraceServiceTest` tag-filter case against the updated dependency.
+- [ ] Run `./gradlew traceRequirements` to confirm the OFT trace remains clean.
+- [ ] Run `./gradlew check`.
+- [ ] Run `./gradlew verifyPlugin`.
diff --git a/doc/changesets/63-show-oft-specification-item-ids-in-markdown-outline.md b/doc/changesets/63-show-oft-specification-item-ids-in-markdown-outline.md
new file mode 100644
index 0000000..02410a3
--- /dev/null
+++ b/doc/changesets/63-show-oft-specification-item-ids-in-markdown-outline.md
@@ -0,0 +1,98 @@
+# GH-63 Show OFT Specification Item IDs in the Markdown Outline
+
+## Goal
+
+Let users see the OpenFastTrace specification item declarations in the Markdown document they are currently reading or editing through the native Markdown Structure / File Structure view. The outline keeps the existing Markdown header hierarchy, lists declarations in source order under the last preceding header, and opens the exact declaration when the user selects an item.
+
+## Scope
+
+In scope:
+
+* Add a Markdown-only outline feature for OpenFastTrace specification item declarations.
+* Preserve the native Markdown header tree and add specification item ID declaration nodes beneath the last preceding header.
+* Show declarations that occur before the first header at the document root.
+* Retain source order among declaration nodes under the same parent.
+* Recognize the existing plain and single-backtick Markdown declaration variants.
+* Navigate from an outline node to the declaration anchor in the focused editor.
+* Rebuild the outline from current document text so unsaved edits are represented.
+* Update requirements, design, user documentation, release notes, and Marketplace change notes for this user-visible feature.
+
+Out of scope:
+
+* RST, plain text, source code, coverage-tag files, and other non-Markdown formats.
+* `Covers:` references, coverage tags, and other non-declaration OFT ID occurrences.
+* Specification titles, trace status, coverage, trace defects, or requirement-network rendering.
+* A separate OFT tool window, a project-wide OFT browser, or replacement of the existing Markdown Structure view or Go to Symbol.
+* New third-party dependencies.
+
+## Design References
+
+* [GH-63](https://github.com/itsallcode/openfasttrace-intellij-plugin/issues/63)
+* [System Requirements](../system_requirements.md)
+* [Solution Strategy](../design/solution_strategy.md)
+* [Building Block View](../design/building_block_view.md)
+* [Runtime View](../design/runtime_view.md)
+* [Quality Requirements](../design/quality_requirements.md)
+* [GH-24 Auto-completion for Covers section](24-auto-completion-for-covers-section.md)
+
+## Strategy
+
+Add a new chain for Markdown specification-item outline navigation. The new requirement must state that only declaration IDs appear, that they retain source order below their last preceding Markdown header, that pre-header declarations appear at the root, and that selecting an item navigates to its declaration after unsaved edits.
+
+Extend the Markdown-specific editor support rather than the project declaration index. Register a `StructureViewExtension` that preserves native Markdown structure nodes and contributes synthetic OFT declaration tree elements. Derive those elements from `OftSyntaxCore.findDefinitionSpecificationItems()` over the focused document text, map their offsets to the last preceding Markdown header, and reuse offset-based editor navigation. This preserves existing Markdown outline behavior and avoids stale index data while the user is editing.
+
+## Task List
+
+- [ ] Create and checkout a new Git branch `feat/63-show-oft-specification-item-ids-in-markdown-outline`
+
+### Requirements And Design
+
+- [ ] Add a feature item for the Markdown OpenFastTrace specification-item outline in `doc/system_requirements.md`.
+- [ ] Add a user requirement stating that the Markdown Structure / File Structure view shows only recognized OFT declaration IDs while preserving Markdown headers.
+- [ ] Add scenarios for placing declaration IDs under their last preceding header in source order, placing pre-header IDs at the root, navigating from an ID, and reflecting unsaved document edits.
+- [ ] Stop and ask user for a review of the system requirements.
+- [ ] Update `doc/design/solution_strategy.md` to record reuse of IntelliJ Structure-view extension APIs and current-document parsing rather than the project index.
+- [ ] Extend `doc/design/building_block_view.md` with a Markdown specification-item outline component and its dependencies on Markdown PSI/Structure infrastructure and the shared syntax core.
+- [ ] Add one runtime design item per outline scenario in `doc/design/runtime_view.md`, covering tree construction and placement, root-level declarations, navigation, and document-change refresh.
+- [ ] Stop and ask user for a review of the design.
+
+### Implementation
+
+- [ ] Add a Markdown Structure-view extension registration without replacing the existing Markdown Structure-view factory.
+- [ ] Implement an immutable, file-local outline model that extracts only `findDefinitionSpecificationItems()` matches from the current Markdown document and retains their source offsets and order.
+- [ ] Implement synthetic, navigable outline tree elements that present the full OFT ID and navigate to its declaration offset in the editor.
+- [ ] Associate each declaration with the closest preceding Markdown header PSI element and contribute it below that header; contribute declarations with no preceding header at the document root.
+- [ ] Preserve all native Markdown header children and ordering while merging OFT declaration nodes, and exclude `Covers:` entries, coverage tags, invalid IDs, and incomplete IDs.
+- [ ] Refresh the outline when the underlying Markdown document changes, including unsaved edits, without using the file-based project index.
+- [ ] Keep the implementation limited to Markdown and IntelliJ Platform APIs; do not change RST, generic text, coverage-tag, project-index, or reference-resolution behavior. Don't use internal or deprecated APIs.
+
+### Verification
+
+- [ ] Add focused syntax/model tests for declaration extraction and source-order/header-association decisions, including plain and single-backtick declaration forms, pre-header declarations, and exclusion of references and invalid or incomplete IDs.
+- [ ] Add IntelliJ light-fixture tests proving that Markdown headers remain present and that OFT IDs appear beneath the last preceding header in source order.
+- [ ] Add IntelliJ light-fixture tests for root-level pre-header IDs, navigation to the exact declaration offset, and outline refresh after an unsaved document edit.
+- [ ] Keep existing syntax, indexing, navigation, completion, and highlighting tests green.
+- [ ] Keep the OpenFastTrace trace clean for the new `feat`, `req`, `scn`, `dsn`, `impl`, and `itest` artifacts in scope.
+- [ ] Keep path coverage at or above 80%.
+- [ ] Keep the dependency policy unchanged; add no third-party dependencies.
+- [ ] Run `./gradlew test`.
+- [ ] Run `./gradlew traceRequirements`.
+- [ ] Run `./gradlew check`.
+- [ ] Run `./gradlew verifyPlugin`.
+- [ ] Keep the SonarQube Cloud quality gate green after CI analysis.
+
+### Update User Documentation
+
+- [ ] Update `README.md` and `doc/user_guide.md` to explain the Markdown Structure / File Structure outline, header placement, declaration-only scope, and navigation behavior.
+
+## Version And Changelog Update
+
+- [ ] Check whether the current project version is the latest GitHub release.
+- [ ] GH-63 is a user-visible feature and therefore requires a minor release.
+- [ ] Raise the version to the selected semantic version.
+- [ ] Write the release-changelog entry for the selected version.
+- [ ] Update to the latest OpenFastTrace library version available on GitHub.
+- [ ] Add `## Bundled OpenFastTrace` followed by `OpenFastTrace ` immediately after the release summary and before the first release category.
+- [ ] Copy the active release notes, including the bundled OpenFastTrace version, into the Marketplace `changeNotes` through the existing Markdown-to-HTML build flow.
+- [ ] Update the release date to the release date.
+- [ ] Ensure the issue list contains `#63: Show OFT Specification Item IDs in the Markdown Outline`.
diff --git a/doc/demo/example/excuse-of-the-day.md b/doc/demo/example/excuse-of-the-day.md
index f927bde..76dadfa 100644
--- a/doc/demo/example/excuse-of-the-day.md
+++ b/doc/demo/example/excuse-of-the-day.md
@@ -25,6 +25,8 @@ Covers:
Needs: scn
+Tags: work
+
## Scenarios
### Pick a Late-Work Excuse
@@ -39,6 +41,8 @@ Covers:
Needs: dsn
+Tags: work
+
## Design
### Random Excuse Selection
diff --git a/doc/design/building_block_view.md b/doc/design/building_block_view.md
index 1fed425..b195b2e 100644
--- a/doc/design/building_block_view.md
+++ b/doc/design/building_block_view.md
@@ -2,31 +2,24 @@
This chapter describes the static decomposition of the plugin into building blocks and their responsibilities.
-The following diagram drafts the current product-level components of the plugin. It shows components, not classes.
+The following feature-focused views show the current product-level components of the plugin. A component may occur in more than one view where it participates in multiple features. The views show components, not classes, and contain at most seven modules each.
+
+## Syntax Highlighting
```plantuml
@startuml
skinparam componentStyle rectangle
+top to bottom direction
package "JetBrains IDE / IntelliJ Platform" {
component "Editor and PSI\nInfrastructure" as IdeEditor
- component "Symbol Search and\nNavigation Infrastructure" as IdeNavigation
- component "Live Template\nInfrastructure" as IdeLiveTemplates
- component "Action System" as IdeActions
- component "Background Task and\nProgress Infrastructure" as IdeTasks
- component "Output View and\nRun Content Infrastructure" as IdeOutput
- component "SM Test Runner\nInfrastructure" as IdeTestRunner
- component "Help Menu and\nWeb View Infrastructure" as IdeHelp
}
package "Opened Project" {
- artifact "Project Content Root" as ProjectRoot
artifact "Markdown and RST\nSpecification Documents" as ProjectSpecs
artifact "Source Files with\nCoverage Tags" as ProjectSources
-}
-
-package "OpenFastTrace Library" {
- component "Trace Engine and\nText Reporter" as OftTraceLibrary
+
+ ProjectSources -[hidden]u- ProjectSpecs
}
package "OpenFastTrace Plugin" {
@@ -34,53 +27,147 @@ package "OpenFastTrace Plugin" {
component "Markdown Specification\nSupport" as MarkdownSupport
component "RST Specification\nSupport" as RstSupport
component "Coverage Tag\nSupport" as CoverageSupport
+}
+
+ProjectSpecs -l-> MarkdownSupport : reads
+ProjectSpecs --> RstSupport : reads
+ProjectSources --> CoverageSupport : reads
+MarkdownSupport -u-> OftSyntax
+RstSupport -u-> OftSyntax
+CoverageSupport -u-> OftSyntax
+MarkdownSupport -d-> IdeEditor
+RstSupport -d-> IdeEditor
+CoverageSupport -d-> IdeEditor
+@enduml
+```
+
+## Specification-Item Navigation and Refactoring
+
+```plantuml
+@startuml
+skinparam componentStyle rectangle
+
+package "JetBrains IDE / IntelliJ Platform" {
+ component "Symbol Search and\nNavigation Infrastructure" as IdeNavigation
+ component "Refactoring and\nUsage Search Infrastructure" as IdeRefactoring
+
+ IdeNavigation -[hidden]u- IdeRefactoring
+}
+
+package "OpenFastTrace Plugin" {
+ component "OFT Syntax Core" as OftSyntax
component "Specification Item\nIndex" as SpecIndex
component "Specification Item\nNavigation" as NavigationSupport
- component "Specification Item\nCompletion" as CompletionSupport
- component "Live Template\nIntegration" as LiveTemplateSupport
- component "Trace Configuration\nIntegration" as TraceConfigurationSupport
- component "Trace Action\nIntegration" as TraceActionSupport
- component "Trace Execution\nService" as TraceExecutionSupport
- component "Trace Output\nPresentation" as TraceOutputSupport
- component "Trace Test Runner\nPresentation" as TraceTestRunnerSupport
- component "User Guide\nIntegration" as UserGuideSupport
+ component "Specification Item\nRefactoring" as RefactoringSupport
}
-MarkdownSupport --> OftSyntax
-RstSupport --> OftSyntax
-CoverageSupport --> OftSyntax
SpecIndex --> OftSyntax
NavigationSupport --> SpecIndex
-TraceActionSupport --> TraceExecutionSupport
-TraceExecutionSupport --> TraceOutputSupport
-TraceExecutionSupport --> TraceTestRunnerSupport
+NavigationSupport -l-> IdeNavigation
+RefactoringSupport --> OftSyntax
+RefactoringSupport --> SpecIndex
+RefactoringSupport --> NavigationSupport
+RefactoringSupport -l-> IdeRefactoring
+@enduml
+```
+
+## Reference Authoring
+
+```plantuml
+@startuml
+skinparam componentStyle rectangle
+
+package "JetBrains IDE / IntelliJ Platform" {
+ component "Editor and PSI\nInfrastructure" as IdeEditor
+ component "Live Template\nInfrastructure" as IdeLiveTemplates
+}
+
+package "OpenFastTrace Plugin" {
+ component "Specification Item\nIndex" as SpecIndex
+ component "Specification Item\nCompletion" as CompletionSupport
+ component "Live Template\nIntegration" as LiveTemplateSupport
+}
-MarkdownSupport --> IdeEditor
-RstSupport --> IdeEditor
-CoverageSupport --> IdeEditor
-SpecIndex --> IdeEditor
-NavigationSupport --> IdeNavigation
CompletionSupport --> SpecIndex
CompletionSupport --> IdeEditor
LiveTemplateSupport --> IdeLiveTemplates
LiveTemplateSupport --> IdeEditor
+@enduml
+```
+
+## Trace Setup
+
+```plantuml
+@startuml
+skinparam componentStyle rectangle
+
+package "JetBrains IDE / IntelliJ Platform" {
+ component "Action System" as IdeActions
+}
+
+package "Opened Project" {
+ artifact "Project Content Root" as ProjectRoot
+}
+
+package "OpenFastTrace Plugin" {
+ component "Trace Configuration\nIntegration" as TraceConfigurationSupport
+ component "Trace Action\nIntegration" as TraceActionSupport
+}
+
TraceConfigurationSupport --> IdeActions
TraceActionSupport --> IdeActions
-TraceExecutionSupport --> IdeTasks
-TraceOutputSupport --> IdeOutput
-TraceTestRunnerSupport --> IdeTestRunner
-TraceTestRunnerSupport --> NavigationSupport
-UserGuideSupport --> IdeHelp
-
TraceActionSupport --> TraceConfigurationSupport
TraceActionSupport --> ProjectRoot : reads path
TraceConfigurationSupport --> ProjectRoot : reads settings roots
-TraceExecutionSupport --> ProjectRoot : traces
+@enduml
+```
+
+## Trace Execution and Results
+
+```plantuml
+@startuml
+skinparam componentStyle rectangle
+
+package "JetBrains IDE / IntelliJ Platform" {
+ component "Background Task and\nProgress Infrastructure" as IdeTasks
+ component "Output View and\nRun Content Infrastructure" as IdeOutput
+ component "SM Test Runner\nInfrastructure" as IdeTestRunner
+}
+
+package "OpenFastTrace Library" {
+ component "Trace Engine and\nText Reporter" as OftTraceLibrary
+}
+
+package "OpenFastTrace Plugin" {
+ component "Trace Execution\nService" as TraceExecutionSupport
+ component "Trace Output\nPresentation" as TraceOutputSupport
+ component "Trace Test Runner\nPresentation" as TraceTestRunnerSupport
+}
+
+TraceExecutionSupport --> IdeTasks
TraceExecutionSupport --> OftTraceLibrary
-MarkdownSupport --> ProjectSpecs : reads
-RstSupport --> ProjectSpecs : reads
-CoverageSupport --> "1..n" ProjectSources : reads
-SpecIndex --> "1..n" ProjectSpecs : indexes
+TraceExecutionSupport --> TraceOutputSupport
+TraceExecutionSupport --> TraceTestRunnerSupport
+TraceOutputSupport --> IdeOutput
+TraceTestRunnerSupport --> IdeTestRunner
+@enduml
+```
+
+## User Guide
+
+```plantuml
+@startuml
+skinparam componentStyle rectangle
+
+package "JetBrains IDE / IntelliJ Platform" {
+ component "Help Menu and\nWeb View Infrastructure" as IdeHelp
+}
+
+package "OpenFastTrace Plugin" {
+ component "User Guide\nIntegration" as UserGuideSupport
+}
+
+UserGuideSupport --> IdeHelp
@enduml
```
@@ -369,6 +456,7 @@ scale 2
. | .
Tags: | "mvp "
. | (comma-separated, empty = all)
+ . | [ ] Include untagged items
. | .
Result view: | () Plain text output
. | (X) IntelliJ Test Runner UI
diff --git a/doc/design/runtime_view.md b/doc/design/runtime_view.md
index 6f966b1..7afcaad 100644
--- a/doc/design/runtime_view.md
+++ b/doc/design/runtime_view.md
@@ -231,7 +231,9 @@ Needs: impl, itest
**Given** a supported specification document contains a `Covers:` entry and the opened project already indexes declared OpenFastTrace specification items
**When** a user invokes IntelliJ basic completion while editing an OFT item ID in that `Covers:` entry
-**Then** the completion component confirms that the caret is inside a `Covers:` reference, loads declared specification item IDs from the declaration index, ranks them by full-ID prefix, name-prefix, name-substring, and artifact-type prefix matches, and shows the ordered suggestions in the standard IDE completion popup.
+**Then** the completion component confirms that the caret is inside a `Covers:` reference, loads declared specification item IDs from the declaration index
+**And** ranks them by full-ID prefix, name-prefix, name-substring, and artifact-type prefix matches
+**And** shows the ordered suggestions in the standard IDE completion popup.
Covers:
- `scn~complete-specification-item-id-in-covers-section~1`
@@ -243,7 +245,8 @@ Needs: impl, itest
**Given** a bundled OFT live template is active at a `COVERED` placeholder under `Covers:` and the opened project already indexes declared OpenFastTrace specification items
**When** a user invokes IntelliJ basic completion in that placeholder before the live-template session ends
-**Then** the completion component reads the active editor document, handles the request like any other `Covers:` reference by reading declared specification item IDs from the declaration index, and shows the matching suggestions in the standard IDE completion popup without ending the live-template session.
+**Then** the completion component reads the active editor document, handles the request like any other `Covers:` reference by reading declared specification item IDs from the declaration index
+**And** shows the matching suggestions in the standard IDE completion popup without ending the live-template session.
Covers:
- `scn~complete-specification-item-id-in-active-live-template-covers-field~1`
@@ -451,7 +454,7 @@ Needs: impl, itest
`dsn~openfasttrace-run-configuration~2`
**When** a user creates or edits an OpenFastTrace run configuration
-**Then** the plugin uses the IntelliJ Run Configuration API (type, factory, configuration) to persist the name, scope, additional paths, artifact type filters, and tag filters. The plugin registers multiple factories to provide pre-configured templates for common scanning scenarios.
+**Then** the plugin uses the IntelliJ Run Configuration API (type, factory, configuration) to persist the name, scope, additional paths, artifact type filters, tag filters, and the `Include untagged items` checkbox. The plugin registers multiple factories to provide pre-configured templates for common scanning scenarios.
Covers:
- `scn~create-and-run-openfasttrace-run-configuration~1`
@@ -474,11 +477,12 @@ Needs: impl, itest
`dsn~filter-trace-by-artifact-types-and-tags~1`
**When** the trace-execution service invokes the OpenFastTrace library
-**Then** it passes the configured artifact type and tag filters from the run configuration to the OpenFastTrace engine to restrict the trace result.
+**Then** it passes the configured artifact type and tag filters, together with the `Include untagged items` setting, from the run configuration to the OpenFastTrace engine to restrict the trace result.
Covers:
- `scn~filter-run-configuration-by-artifact-types~1`
- `scn~filter-run-configuration-by-tags~1`
+- `scn~filter-run-configuration-by-untagged-items~1`
Needs: impl, itest
diff --git a/doc/system_requirements.md b/doc/system_requirements.md
index eb52a6d..f9d09bf 100644
--- a/doc/system_requirements.md
+++ b/doc/system_requirements.md
@@ -463,7 +463,7 @@ Needs: scn
### Filter Trace by Tags
`req~filter-trace-by-tags~1`
-When using an OpenFastTrace run configuration, the plugin lets users filter the trace results by tags. Users can specify a comma-separated list of tags to focus the trace on tagged specification items.
+When using an OpenFastTrace run configuration, the plugin lets users filter the trace results by tags. Users can specify a comma-separated list of tags to focus the trace on tagged specification items and can select an `Include untagged items` checkbox below the Tags field to also include specification items without tags.
Covers:
- `feat~oft-run-configurations~2`
@@ -1356,6 +1356,18 @@ Covers:
Needs: dsn
+### Filter Run Configuration by Untagged Items
+`scn~filter-run-configuration-by-untagged-items~1`
+
+**Given** an IntelliJ project is open and an `OpenFastTrace` run configuration has the `Include untagged items` checkbox selected
+**When** a user runs that configuration
+**Then** the plugin passes the untagged-item filter to OpenFastTrace and the resulting trace output contains only specification items without tags.
+
+Covers:
+- `req~filter-trace-by-tags~1`
+
+Needs: dsn
+
### Test Runner as Default Run Configuration Result View
`scn~test-runner-as-default-run-configuration-result-view~1`
diff --git a/doc/user_guide.md b/doc/user_guide.md
index 445d7d7..0fe1eb5 100644
--- a/doc/user_guide.md
+++ b/doc/user_guide.md
@@ -136,7 +136,7 @@ Use OpenFastTrace run configurations when you need multiple repeatable trace set
1. Open the run/debug configuration menu.
2. Choose `Edit Configurations...`.
3. Add a new `OpenFastTrace` configuration.
-4. Configure the trace scope, artifact types, tags, and result view.
+4. Configure the trace scope, artifact types, tags, whether to include untagged items, and the result view.
5. Save and run the configuration from the IDE toolbar.
Run configurations provide the same trace-scope controls in the configuration editor.
@@ -148,6 +148,8 @@ They also let you choose the result view:
Use run configurations for recurring workflows such as tracing only a subsystem, tracing only requirement and design layers, or tracing a document set with a specific tag.
+To include specification items without tags, select `Include untagged items` directly below the Tags field.
+

## Read Trace Results
diff --git a/gradle.lockfile b/gradle.lockfile
index 605d7b6..d3dae6f 100644
--- a/gradle.lockfile
+++ b/gradle.lockfile
@@ -34,21 +34,23 @@ org.assertj:assertj-core:4.0.0-M1=intellijPlatformTestClasspath,intellijPlatform
org.hamcrest:hamcrest-core:1.3=intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,testCompileClasspath,testRuntimeClasspath
org.hamcrest:hamcrest:2.2=intellijPlatformTestClasspath,intellijPlatformTestDependencies
org.hamcrest:hamcrest:3.0=intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-api:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-core:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-exporter-common:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-exporter-specobject:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-importer-lightweightmarkup:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-importer-markdown:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-importer-restructuredtext:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-importer-specobject:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-importer-tag:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-importer-xmlparser:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-importer-zip:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-reporter-aspec:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-reporter-html:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace-reporter-plaintext:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
-org.itsallcode.openfasttrace:openfasttrace:4.5.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-api:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-core:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-exporter-common:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-exporter-specobject:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-importer-lightweightmarkup:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-importer-gherkin:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-importer-markdown:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-importer-restructuredtext:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-importer-specobject:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-importer-tag:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-importer-tag-importer-common:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-importer-xmlparser:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-importer-zip:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-reporter-aspec:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-reporter-html:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace-reporter-plaintext:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
+org.itsallcode.openfasttrace:openfasttrace:4.8.0=compileClasspath,intellijPlatformComposedJar,intellijPlatformRuntimeClasspath,intellijPlatformTestRuntimeClasspath,intellijPlatformTestRuntimeClasspath_manualTestIde,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.jacoco:org.jacoco.agent:0.8.13=jacocoAgent,jacocoAnt
org.jacoco:org.jacoco.ant:0.8.13=jacocoAnt
org.jacoco:org.jacoco.core:0.8.13=jacocoAnt
diff --git a/gradle.properties b/gradle.properties
index 8eef264..f7a0093 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-version=0.9.0
+version=0.10.0
org.gradle.configuration-cache=true
org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index df6a6ad..a9db115 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
networkTimeout=10000
retries=0
retryBackOffMs=500
diff --git a/gradlew b/gradlew
index b9bb139..249efbb 100755
--- a/gradlew
+++ b/gradlew
@@ -20,7 +20,7 @@
##############################################################################
#
-# Gradle start up script for POSIX generated by Gradle.
+# gradlew start up script for POSIX generated by Gradle.
#
# Important for running:
#
@@ -29,7 +29,7 @@
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
-# ksh Gradle
+# ksh gradlew
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
diff --git a/gradlew.bat b/gradlew.bat
index 24c62d5..a51ec4f 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -19,7 +19,7 @@
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
-@rem Gradle startup script for Windows
+@rem gradlew startup script for Windows
@rem
@rem ##########################################################################
@@ -72,7 +72,7 @@ echo location of your Java installation. 1>&2
-@rem Execute Gradle
+@rem Execute gradlew
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
@rem which allows us to clear the local environment before executing the java command
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
diff --git a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/OftSupportedFiles.java b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/OftSupportedFiles.java
index ee90247..3bd9b4d 100644
--- a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/OftSupportedFiles.java
+++ b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/OftSupportedFiles.java
@@ -29,6 +29,7 @@ public final class OftSupportedFiles {
"robot",
"r",
"rs",
+ "dox",
"sv", "v", "inc",
"sh", "bash", "zsh",
"swift",
diff --git a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceInputResolver.java b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceInputResolver.java
index 343318e..54e574e 100644
--- a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceInputResolver.java
+++ b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceInputResolver.java
@@ -106,7 +106,8 @@ static OftTraceInputResolution resolveProjectRoot(final String basePath, final O
return OftTraceInputResolution.valid(OftTraceInputs.wholeProject(
inputPath,
settings.artifactTypes(),
- settings.tags()
+ settings.tags(),
+ settings.includeUntagged()
));
}
@@ -123,7 +124,8 @@ private static OftTraceInputResolution resolveFromProjectRoot(
return OftTraceInputResolution.valid(OftTraceInputs.wholeProject(
projectRoot,
settings.artifactTypes(),
- settings.tags()
+ settings.tags(),
+ settings.includeUntagged()
));
}
final LinkedHashSet inputs = new LinkedHashSet<>();
@@ -152,7 +154,8 @@ private static OftTraceInputResolution resolveFromProjectRoot(
return OftTraceInputResolution.valid(OftTraceInputs.selectedResources(
List.copyOf(inputs),
settings.artifactTypes(),
- settings.tags()
+ settings.tags(),
+ settings.includeUntagged()
));
}
@@ -218,7 +221,8 @@ private static OftTraceInputResolution resolveConfiguredAdditionalPath(
return OftTraceInputResolution.valid(OftTraceInputs.selectedResources(
List.of(resolvedPath),
settings.artifactTypes(),
- settings.tags()
+ settings.tags(),
+ settings.includeUntagged()
));
}
diff --git a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceInputs.java b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceInputs.java
index 3f2d686..c0937b0 100644
--- a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceInputs.java
+++ b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceInputs.java
@@ -8,17 +8,20 @@ public final class OftTraceInputs {
private final List inputPaths;
private final List artifactTypes;
private final List tags;
+ private final boolean includeUntagged;
private OftTraceInputs(
final boolean wholeProject,
final List inputPaths,
final List artifactTypes,
- final List tags
+ final List tags,
+ final boolean includeUntagged
) {
this.wholeProject = wholeProject;
this.inputPaths = List.copyOf(inputPaths);
this.artifactTypes = List.copyOf(artifactTypes);
this.tags = List.copyOf(tags);
+ this.includeUntagged = includeUntagged;
}
public static OftTraceInputs wholeProject(
@@ -26,7 +29,16 @@ public static OftTraceInputs wholeProject(
final List artifactTypes,
final List tags
) {
- return new OftTraceInputs(true, List.of(projectRoot), artifactTypes, tags);
+ return new OftTraceInputs(true, List.of(projectRoot), artifactTypes, tags, false);
+ }
+
+ public static OftTraceInputs wholeProject(
+ final Path projectRoot,
+ final List artifactTypes,
+ final List tags,
+ final boolean includeUntagged
+ ) {
+ return new OftTraceInputs(true, List.of(projectRoot), artifactTypes, tags, includeUntagged);
}
public static OftTraceInputs selectedResources(
@@ -34,7 +46,16 @@ public static OftTraceInputs selectedResources(
final List artifactTypes,
final List tags
) {
- return new OftTraceInputs(false, inputPaths, artifactTypes, tags);
+ return new OftTraceInputs(false, inputPaths, artifactTypes, tags, false);
+ }
+
+ public static OftTraceInputs selectedResources(
+ final List inputPaths,
+ final List artifactTypes,
+ final List tags,
+ final boolean includeUntagged
+ ) {
+ return new OftTraceInputs(false, inputPaths, artifactTypes, tags, includeUntagged);
}
public boolean isWholeProject() {
@@ -53,6 +74,10 @@ public List tags() {
return tags;
}
+ public boolean includeUntagged() {
+ return includeUntagged;
+ }
+
String progressText() {
if (wholeProject) {
return inputPaths.getFirst().toString();
diff --git a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceService.java b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceService.java
index c8376e7..25dd089 100644
--- a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceService.java
+++ b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceService.java
@@ -22,6 +22,7 @@
import java.util.stream.Collectors;
public final class OftTraceService {
+ private static final String UNTAGGED_ITEMS_FILTER_MARKER = "__oft-include-untagged__!";
@SuppressWarnings("java:S3032")
// OFT ServiceLoader discovery must use the plugin class loader, not an arbitrary caller context loader.
private static final ClassLoader PLUGIN_CLASS_LOADER = OftTraceService.class.getClassLoader();
@@ -48,10 +49,16 @@ public OftTraceResult traceProject(final OftTraceInputs inputs, final OftTracePr
try {
progress.phase("Importing OpenFastTrace items...", 0.15D);
progress.checkCanceled();
- final FilterSettings filterSettings = FilterSettings.builder()
- .artifactTypes(Set.copyOf(inputs.artifactTypes()))
- .tags(Set.copyOf(inputs.tags()))
- .build();
+ final FilterSettings.Builder filterSettings = FilterSettings.builder();
+ if (!inputs.artifactTypes().isEmpty()) {
+ filterSettings.artifactTypes(Set.copyOf(inputs.artifactTypes()));
+ }
+ final Set tags = createTagFilter(inputs);
+ if (!tags.isEmpty()) {
+ filterSettings.tags(tags);
+ // OFT defaults to "without tags" mode unless this is explicitly disabled.
+ filterSettings.withoutTags(inputs.includeUntagged());
+ }
final List items = importItems(inputs.inputPaths(), filterSettings);
progress.phase("Linking OpenFastTrace items...", 0.4D);
@@ -75,10 +82,10 @@ public OftTraceResult traceProject(final OftTraceInputs inputs, final OftTracePr
}
- private List importItems(final List inputs, final FilterSettings filterSettings) {
+ private List importItems(final List inputs, final FilterSettings.Builder filterSettings) {
final ImportSettings settings = ImportSettings.builder()
.addInputs(inputs)
- .filter(filterSettings)
+ .filter(filterSettings.build())
.build();
return runWithPluginClassLoader(() -> oft.importItems(settings));
}
@@ -117,6 +124,17 @@ private static ReportSettings createReportSettings() {
.build();
}
+ private static Set createTagFilter(final OftTraceInputs inputs) {
+ if (!inputs.includeUntagged() && inputs.tags().isEmpty()) {
+ return Set.of();
+ }
+ final Set tags = new java.util.LinkedHashSet<>(inputs.tags());
+ if (inputs.includeUntagged()) {
+ tags.add(UNTAGGED_ITEMS_FILTER_MARKER);
+ }
+ return tags;
+ }
+
private static T runWithPluginClassLoader(final Callable action) {
final Thread currentThread = Thread.currentThread();
final ClassLoader previousClassLoader = currentThread.getContextClassLoader();
diff --git a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceSettingsComponent.java b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceSettingsComponent.java
index d8c0074..b0646d8 100644
--- a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceSettingsComponent.java
+++ b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceSettingsComponent.java
@@ -30,6 +30,8 @@ public final class OftTraceSettingsComponent {
private final JBTextArea additionalPathsTextArea = new JBTextArea();
private final JBTextField artifactTypesField = new JBTextField();
private final JBTextField tagsField = new JBTextField();
+ private final JBCheckBox includeUntaggedCheckBox =
+ new JBCheckBox("Include untagged items");
private final JBRadioButton plainTextResultViewRadioButton =
new JBRadioButton("Plain text output");
private final JBRadioButton testRunnerResultViewRadioButton =
@@ -101,7 +103,8 @@ public void changedUpdate(final DocumentEvent event) {
.addLabeledComponent("Artifact types:", artifactTypesField)
.addTooltip("comma-separated, empty = all")
.addLabeledComponent("Tags:", tagsField)
- .addTooltip("comma-separated, empty = all");
+ .addTooltip("comma-separated, empty = all")
+ .addLabeledComponent("", includeUntaggedCheckBox);
if (showResultViewSelection) {
formBuilder
.addSeparator()
@@ -129,6 +132,7 @@ public OftTraceSettingsSnapshot getSettings() {
additionalPathsTextArea.getText(),
artifactTypesField.getText(),
tagsField.getText(),
+ includeUntaggedCheckBox.isSelected(),
selectedResultView()
);
}
@@ -141,6 +145,7 @@ public void setSettings(final OftTraceSettingsSnapshot settings) {
additionalPathsTextArea.setText(settings.additionalPathsText());
artifactTypesField.setText(settings.artifactTypesText());
tagsField.setText(settings.tagsText());
+ includeUntaggedCheckBox.setSelected(settings.includeUntagged());
plainTextResultViewRadioButton.setSelected(settings.resultView() == OftTraceResultView.PLAIN_TEXT);
testRunnerResultViewRadioButton.setSelected(settings.resultView() == OftTraceResultView.TEST_RUNNER);
updateSelectedResourcesEnabledState();
diff --git a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceSettingsSnapshot.java b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceSettingsSnapshot.java
index dcac0ec..349faef 100644
--- a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceSettingsSnapshot.java
+++ b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceSettingsSnapshot.java
@@ -10,6 +10,7 @@ public record OftTraceSettingsSnapshot(
String additionalPathsText,
String artifactTypesText,
String tagsText,
+ boolean includeUntagged,
OftTraceResultView resultView
) {
public static final OftTraceSettingsSnapshot DEFAULT = new OftTraceSettingsSnapshot(
@@ -19,6 +20,7 @@ public record OftTraceSettingsSnapshot(
"doc/",
"",
"",
+ false,
OftTraceResultView.TEST_RUNNER
);
@@ -40,10 +42,32 @@ public OftTraceSettingsSnapshot(
additionalPathsText,
artifactTypesText,
tagsText,
+ false,
DEFAULT.resultView()
);
}
+ public OftTraceSettingsSnapshot(
+ final OftTraceScopeMode scopeMode,
+ final boolean includeSourceRoots,
+ final boolean includeTestRoots,
+ final String additionalPathsText,
+ final String artifactTypesText,
+ final String tagsText,
+ final OftTraceResultView resultView
+ ) {
+ this(
+ scopeMode,
+ includeSourceRoots,
+ includeTestRoots,
+ additionalPathsText,
+ artifactTypesText,
+ tagsText,
+ false,
+ resultView
+ );
+ }
+
public List additionalPaths() {
return LINE_SEPARATOR.splitAsStream(additionalPathsText)
.map(String::trim)
diff --git a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfiguration.java b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfiguration.java
index cb5b6ee..253f136 100644
--- a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfiguration.java
+++ b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfiguration.java
@@ -50,6 +50,7 @@ public OftTraceSettingsSnapshot snapshot() {
state.getAdditionalPathsText(),
state.getArtifactTypesText(),
state.getTagsText(),
+ state.isIncludeUntagged(),
parseResultView(state.getResultView())
);
}
@@ -61,6 +62,7 @@ public void updateFrom(final OftTraceSettingsSnapshot snapshot) {
state.setAdditionalPathsText(snapshot.additionalPathsText());
state.setArtifactTypesText(snapshot.artifactTypesText());
state.setTagsText(snapshot.tagsText());
+ state.setIncludeUntagged(snapshot.includeUntagged());
state.setResultView(snapshot.resultView().name());
}
@@ -111,6 +113,7 @@ private static final class State implements Serializable {
private String additionalPathsText = OftTraceSettingsSnapshot.DEFAULT.additionalPathsText();
private String artifactTypesText = OftTraceSettingsSnapshot.DEFAULT.artifactTypesText();
private String tagsText = OftTraceSettingsSnapshot.DEFAULT.tagsText();
+ private boolean includeUntagged = OftTraceSettingsSnapshot.DEFAULT.includeUntagged();
private String resultView = OftTraceSettingsSnapshot.DEFAULT.resultView().name();
public String getTraceScopeMode() {
@@ -161,6 +164,14 @@ public void setTagsText(final String tagsText) {
this.tagsText = tagsText;
}
+ public boolean isIncludeUntagged() {
+ return includeUntagged;
+ }
+
+ public void setIncludeUntagged(final boolean includeUntagged) {
+ this.includeUntagged = includeUntagged;
+ }
+
public String getResultView() {
return resultView;
}
diff --git a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfigurationFactory.java b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfigurationFactory.java
index 1fc20b9..60ccf22 100644
--- a/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfigurationFactory.java
+++ b/src/main/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfigurationFactory.java
@@ -3,8 +3,8 @@
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.execution.configurations.RunConfigurationSingletonPolicy;
import com.intellij.openapi.project.Project;
-import org.itsallcode.openfasttrace.intellijplugin.trace.OftTraceSettingsSnapshot;
import org.jetbrains.annotations.NotNull;
import java.util.function.Consumer;
@@ -35,6 +35,11 @@ public OftRunConfigurationFactory(
return configuration;
}
+ @Override
+ public @NotNull RunConfigurationSingletonPolicy getSingletonPolicy() {
+ return RunConfigurationSingletonPolicy.SINGLE_INSTANCE_ONLY;
+ }
+
@Override
public @NotNull String getName() {
return this.factoryName;
diff --git a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/OftMarketplaceMetadataTest.java b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/OftMarketplaceMetadataTest.java
index 5d119b1..ab9d8da 100644
--- a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/OftMarketplaceMetadataTest.java
+++ b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/OftMarketplaceMetadataTest.java
@@ -45,9 +45,6 @@ void givenActiveReleaseNotesWhenReadingThenItContainsMarketplaceMetadataEntry()
Assertions.assertAll(
() -> assertThat(releaseNotes, containsString("# OpenFastTrace IntelliJ Plugin " + version)),
- () -> assertThat(releaseNotes, containsString("#51: Complete Marketplace-facing plugin metadata")),
- () -> assertThat(releaseNotes, containsString("clearer overview")),
- () -> assertThat(releaseNotes, containsString("installing or updating")),
() -> assertThat(releaseNotes, containsString("## Bundled OpenFastTrace")),
() -> assertThat(releaseNotes, containsString("OpenFastTrace " + bundledOpenFastTraceVersion))
);
diff --git a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceRunContentOutputPresenterTest.java b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceRunContentOutputPresenterTest.java
index 90b0275..8367c5e 100644
--- a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceRunContentOutputPresenterTest.java
+++ b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceRunContentOutputPresenterTest.java
@@ -71,7 +71,7 @@ public void testGivenTwoThousandUncoveredRequirementsWhenPresentedThenTheIdeCons
assertThat(renderedOutput, Matchers.containsString(LAST_ITEM_ID));
assertThat(consoleText, Matchers.containsString(FIRST_ITEM_ID));
assertThat(consoleText, Matchers.containsString(LAST_ITEM_ID));
- assertThat(consoleText, Matchers.containsString("not ok - 2000 total, 2000 defect"));
+ assertThat(consoleText, Matchers.containsString("not ok - 2000 total, 2000 direct, 0 transitive defects"));
assertThat(stripAnsi(consoleText), is(expectedConsoleText(renderedOutput)));
} finally {
disposeConsole(consoleRef.get());
diff --git a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceServiceTest.java b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceServiceTest.java
index 1c34744..b2b574d 100644
--- a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceServiceTest.java
+++ b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/OftTraceServiceTest.java
@@ -3,9 +3,11 @@
import org.itsallcode.openfasttrace.core.Oft;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import java.io.IOException;
import java.lang.reflect.Proxy;
@@ -13,6 +15,7 @@
import java.nio.file.Path;
import java.net.URLClassLoader;
import java.util.List;
+import java.util.stream.Stream;
import java.util.regex.Pattern;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -151,7 +154,7 @@ void testGivenUncleanTraceChainWhenTracingThenItReportsTheExpectedDefectCountInT
Assertions.assertAll(
() -> assertThat(result.isSuccessful(), is(false)),
() -> assertThat(result.output(), Matchers.containsString("\u001B[")),
- () -> assertThat(renderedOutput, Matchers.containsString("not ok - 3 total, 3 defect")),
+ () -> assertThat(renderedOutput, Matchers.containsString("not ok - 3 total, 1 direct, 2 transitive defects")),
() -> assertThat(renderedOutput, Matchers.containsString("dsn~chain_design~1")),
() -> assertThat(renderedOutput, Matchers.containsString("feat~chain_feature~1")),
() -> assertThat(renderedOutput, Matchers.containsString("req~chain_requirement~1"))
@@ -206,55 +209,51 @@ void testGivenArtifactTypeFilterMatchingRequirementWhenTracingThenItIncludesTheR
OftTraceProgress.NONE
);
final String renderedOutput = stripAnsi(result.output());
- System.out.println(renderedOutput);
Assertions.assertAll(
() -> assertThat(result.isSuccessful(), is(true)),
() -> assertThat(renderedOutput, Matchers.containsString("ok - 2 total"))
);
}
- @Disabled("Reanable after https://github.com/itsallcode/openfasttrace/issues/505 is fixed")
- @Test
- void testGivenTagFilterMatchingArtifactWhenTracingThenItIncludesTheArtifact(
+
+ private static Stream tagFilterScenarios() {
+ return Stream.of(
+ Arguments.of("work", false, "ok - 2 total"),
+ Arguments.of("work, home", false, "ok - 3 total"),
+ Arguments.of("", false, "ok - 4 total"),
+ Arguments.of("", true, "ok - 1 total")
+ );
+ }
+
+ // [itest->dsn~filter-trace-by-artifact-types-and-tags~1]
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("tagFilterScenarios")
+ void testGivenTagFilterWhenTracingThenItIncludesOnlyMatchingItems(
+ final String tagsText,
+ final boolean includeUntagged,
+ final String expectedSummaryLine,
@TempDir final Path temporaryDirectory
) throws IOException {
- final Path docDirectory = Files.createDirectories(temporaryDirectory.resolve("doc"));
- Files.writeString(
- docDirectory.resolve("tags.md"),
- """
- ### Tagged Requirement
- `req~tagged_requirement~1`
-
- Tags: tagged
-
- Needs: impl
-
- ### Untagged Requirement
- `req~untagged_requirement~1`
-
- Needs: impl
-
- ### Tagged Coverage
- `impl~tagged_coverage~1`
-
- Covers:
- - `req~tagged_requirement~1`
-
- Tags: tagged
- """
- );
+ writeTagFilterProject(temporaryDirectory);
final OftTraceResult result = new OftTraceService().traceProject(
OftTraceInputs.selectedResources(
java.util.List.of(temporaryDirectory),
java.util.List.of(),
- java.util.List.of("tagged")
+ tagsText.isEmpty() ? java.util.List.of() : java.util.Arrays.stream(tagsText.split(","))
+ .map(String::trim)
+ .filter(tag -> !tag.isEmpty())
+ .toList(),
+ includeUntagged
),
OftTraceProgress.NONE
);
final String renderedOutput = stripAnsi(result.output());
- assertThat(renderedOutput, Matchers.containsString("ok - 2 total"));
+ Assertions.assertAll(
+ () -> assertThat(result.isSuccessful(), is(true)),
+ () -> assertThat(renderedOutput, Matchers.containsString(expectedSummaryLine))
+ );
}
private String stripAnsi(final String output) {
@@ -366,4 +365,27 @@ private void writeOutOfScopeDefect(final Path projectRoot) throws IOException {
"""
);
}
+
+ private void writeTagFilterProject(final Path projectRoot) throws IOException {
+ final Path docDirectory = Files.createDirectories(projectRoot.resolve("doc"));
+ Files.writeString(
+ docDirectory.resolve("tags.md"),
+ """
+ ### Work Requirement
+ `req~tagged_work_requirement~1`
+ Tags: work
+
+ ### Work and Home Requirement
+ `req~tagged_work_home_requirement~1`
+ Tags: work, home
+
+ ### Home Requirement
+ `req~tagged_home_requirement~1`
+ Tags: home
+
+ ### Untagged Requirement
+ `req~untagged_requirement~1`
+ """
+ );
+ }
}
diff --git a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfigurationSettingsEditorTest.java b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfigurationSettingsEditorTest.java
index 05d287d..edcb570 100644
--- a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfigurationSettingsEditorTest.java
+++ b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfigurationSettingsEditorTest.java
@@ -39,6 +39,7 @@ public void testGivenEditorWhenResettingFromConfigurationThenItUpdatesUI() {
"additional",
"dsn",
"mvp",
+ true,
OftTraceResultView.TEST_RUNNER
);
configuration.updateFrom(snapshot);
@@ -54,6 +55,7 @@ public void testGivenEditorWhenResettingFromConfigurationThenItUpdatesUI() {
() -> assertThat(uiSettings.additionalPathsText(), is(snapshot.additionalPathsText())),
() -> assertThat(uiSettings.artifactTypesText(), is(snapshot.artifactTypesText())),
() -> assertThat(uiSettings.tagsText(), is(snapshot.tagsText())),
+ () -> assertThat(uiSettings.includeUntagged(), is(snapshot.includeUntagged())),
() -> assertThat(uiSettings.resultView(), is(snapshot.resultView()))
);
}
@@ -69,6 +71,7 @@ public void testGivenEditorWhenApplyingToConfigurationThenItUpdatesConfiguration
"more paths",
"req",
"tag",
+ true,
OftTraceResultView.TEST_RUNNER
);
editor.component.setSettings(snapshot);
@@ -84,6 +87,7 @@ public void testGivenEditorWhenApplyingToConfigurationThenItUpdatesConfiguration
() -> assertThat(stored.additionalPathsText(), is(snapshot.additionalPathsText())),
() -> assertThat(stored.artifactTypesText(), is(snapshot.artifactTypesText())),
() -> assertThat(stored.tagsText(), is(snapshot.tagsText())),
+ () -> assertThat(stored.includeUntagged(), is(snapshot.includeUntagged())),
() -> assertThat(stored.resultView(), is(snapshot.resultView()))
);
}
@@ -98,6 +102,7 @@ public void testGivenEditorWithMissingAdditionalPathWhenUpdatingSettingsThenItSh
"missing",
"",
"",
+ false,
OftTraceResultView.TEST_RUNNER
));
diff --git a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfigurationTest.java b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfigurationTest.java
index 90932a2..aaf5aa0 100644
--- a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfigurationTest.java
+++ b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunConfigurationTest.java
@@ -1,6 +1,7 @@
package org.itsallcode.openfasttrace.intellijplugin.trace.runconfig;
import com.intellij.execution.configurations.ConfigurationFactory;
+import com.intellij.execution.configurations.RunConfigurationSingletonPolicy;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
@@ -15,6 +16,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.api.function.Executable;
import java.util.Arrays;
@@ -25,6 +27,7 @@
import static org.hamcrest.Matchers.sameInstance;
// [itest->dsn~openfasttrace-run-configuration~2]
+@SuppressWarnings("JUnitMixedFramework")
public class OftRunConfigurationTest extends AbstractOftPlatformTestCase {
@BeforeEach
void initPlatformFixture() throws Exception {
@@ -55,6 +58,7 @@ public void testGivenRunConfigurationWhenUpdatingFromSnapshotThenItStoresTheSett
"additional",
"dsn",
"mvp",
+ true,
OftTraceResultView.TEST_RUNNER
);
@@ -68,6 +72,7 @@ public void testGivenRunConfigurationWhenUpdatingFromSnapshotThenItStoresTheSett
() -> assertThat(stored.additionalPathsText(), is(snapshot.additionalPathsText())),
() -> assertThat(stored.artifactTypesText(), is(snapshot.artifactTypesText())),
() -> assertThat(stored.tagsText(), is(snapshot.tagsText())),
+ () -> assertThat(stored.includeUntagged(), is(snapshot.includeUntagged())),
() -> assertThat(stored.resultView(), is(snapshot.resultView()))
);
}
@@ -84,6 +89,7 @@ public void testGivenRunConfigurationWithSettingsWhenWritingAndReadingExternalTh
"additional",
"dsn",
"mvp",
+ true,
OftTraceResultView.TEST_RUNNER
);
configuration.updateFrom(snapshot);
@@ -102,6 +108,7 @@ public void testGivenRunConfigurationWithSettingsWhenWritingAndReadingExternalTh
() -> assertThat(stored.additionalPathsText(), is(snapshot.additionalPathsText())),
() -> assertThat(stored.artifactTypesText(), is(snapshot.artifactTypesText())),
() -> assertThat(stored.tagsText(), is(snapshot.tagsText())),
+ () -> assertThat(stored.includeUntagged(), is(snapshot.includeUntagged())),
() -> assertThat(stored.resultView(), is(snapshot.resultView()))
);
}
@@ -157,6 +164,20 @@ public void testGivenRunConfigurationTypeWhenCheckingFactoriesThenItContainsAllT
));
}
+ // [itest->dsn~trace-configuration-integration~2]
+ public void testGivenRunConfigurationTypeWhenCheckingFactorySingletonPolicyThenItDisallowsMultipleInstances() {
+ final OftRunConfigurationType type = new OftRunConfigurationType();
+
+ Assertions.assertAll(
+ Arrays.stream(type.getConfigurationFactories())
+ .map(factory -> (Executable) () -> {
+ final OftRunConfigurationFactory oftFactory = (OftRunConfigurationFactory) factory;
+ assertThat(oftFactory.getSingletonPolicy(), is(RunConfigurationSingletonPolicy.SINGLE_INSTANCE_ONLY));
+ })
+ .toList()
+ );
+ }
+
@ParameterizedTest(name = "{0}")
@CsvSource({
"'User requirements', false, false, false, 'doc/', 'feat, req, scn, bconstr'",
@@ -182,7 +203,9 @@ void testGivenRunConfigurationTemplateWhenCreatingConfigurationThenItHasCorrectS
() -> assertThat(snapshot.includeSourceRoots(), is(includeSourceRoots)),
() -> assertThat(snapshot.includeTestRoots(), is(includeTestRoots)),
() -> assertThat(snapshot.additionalPathsText(), is(additionalPathsText)),
- () -> assertThat(snapshot.artifactTypesText(), is(artifactTypesText))
+ () -> assertThat(snapshot.artifactTypesText(), is(artifactTypesText)),
+ () -> assertThat(snapshot.tagsText(), is("")),
+ () -> assertThat(snapshot.includeUntagged(), is(false))
);
}
diff --git a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunProfileStateTest.java b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunProfileStateTest.java
index 5e8a8f3..bbc0cf9 100644
--- a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunProfileStateTest.java
+++ b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/trace/runconfig/OftRunProfileStateTest.java
@@ -18,7 +18,7 @@
public class OftRunProfileStateTest extends AbstractOftPlatformTestCase {
// [itest->dsn~trace-action-integration~3]
- public void testExecuteReturnsNotNull() throws Exception {
+ public void testExecuteReturnsNotNull() {
final ExecutionEnvironment environment = createEnvironment();
final OftRunProfileState state = new OftRunProfileState(
environment,
@@ -34,7 +34,7 @@ public void testExecuteReturnsNotNull() throws Exception {
}
// [itest->dsn~select-plain-text-trace-result-view~1]
- public void testGivenPlainTextResultViewWhenExecutingThenItUsesPlainTextConsole() throws Exception {
+ public void testGivenPlainTextResultViewWhenExecutingThenItUsesPlainTextConsole() {
final ExecutionEnvironment environment = createEnvironment();
final OftRunProfileState state = new OftRunProfileState(
environment,
@@ -48,7 +48,7 @@ public void testGivenPlainTextResultViewWhenExecutingThenItUsesPlainTextConsole(
}
// [itest->dsn~test-runner-as-default-run-configuration-result-view~1]
- public void testGivenDefaultResultViewWhenExecutingThenItUsesTestRunnerConsole() throws Exception {
+ public void testGivenDefaultResultViewWhenExecutingThenItUsesTestRunnerConsole() {
final ExecutionEnvironment environment = createEnvironment();
final OftRunProfileState state = new OftRunProfileState(
environment,
@@ -62,7 +62,7 @@ public void testGivenDefaultResultViewWhenExecutingThenItUsesTestRunnerConsole()
}
// [itest->dsn~select-test-runner-trace-result-view~1]
- public void testGivenTestRunnerResultViewWhenExecutingThenItUsesTestRunnerConsole() throws Exception {
+ public void testGivenTestRunnerResultViewWhenExecutingThenItUsesTestRunnerConsole() {
final ExecutionEnvironment environment = createEnvironment();
final OftRunProfileState state = new OftRunProfileState(
environment,