diff --git a/.github/workflows/broken_links_checker.yml b/.github/workflows/broken_links_checker.yml
index 9c5b1e3..80a78d3 100644
--- a/.github/workflows/broken_links_checker.yml
+++ b/.github/workflows/broken_links_checker.yml
@@ -11,12 +11,14 @@ jobs:
permissions:
contents: read
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
+ with:
+ persist-credentials: false
- name: Configure broken links checker
run: |
mkdir -p ./target
echo '{ "aliveStatusCodes": [429, 200] }' > ./target/broken_links_checker.json
- - uses: gaurav-nelson/github-action-markdown-link-check@v1
+ - uses: tcort/github-action-markdown-link-check@v1
with:
use-quiet-mode: 'yes'
use-verbose-mode: 'yes'
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 8c6415f..6425852 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -12,13 +12,15 @@ jobs:
contents: read
strategy:
- fail-fast: true
+ fail-fast: false
matrix:
- java: [17]
- os: [ubuntu-latest, macos-latest, windows-latest]
+ java: [17, 21, 25]
+ os: [ubuntu-latest]
include:
- - os: ubuntu-latest
- java: 21
+ - os: macos-latest
+ java: 17
+ - os: windows-latest
+ java: 17
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-os-${{ matrix.os }}-java-${{ matrix.java }}
@@ -35,21 +37,20 @@ jobs:
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
with:
fetch-depth: 0
+ persist-credentials: false
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
- java-version: |
- 17
- 21
+ java-version: ${{ matrix.java }}
cache: 'maven'
- name: Cache SonarQube packages
if: ${{ env.DEFAULT_OS == matrix.os && env.DEFAULT_JAVA == matrix.java }}
- uses: actions/cache@v4
+ uses: actions/cache@v5
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
@@ -58,12 +59,14 @@ jobs:
- name: Build with Java ${{ matrix.java }}
run: |
mvn --batch-mode -T 1C clean org.jacoco:jacoco-maven-plugin:prepare-agent install \
+ -DossindexSkip=true \
-Djava.version=${{ matrix.java }}
- name: Sonar analysis
if: ${{ env.DEFAULT_OS == matrix.os && env.DEFAULT_JAVA == matrix.java && env.SONAR_TOKEN != null }}
run: |
mvn --batch-mode org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \
+ -DossindexSkip=true \
-Dsonar.token=$SONAR_TOKEN
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -72,10 +75,41 @@ jobs:
- name: Verify reproducible build
run: |
mvn --batch-mode -T 1C clean verify artifact:compare -DskipTests \
+ -DossindexSkip=true \
-Djava.version=${{ matrix.java }}
- build:
- needs: matrix-build
+ ossindex:
runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ persist-credentials: false
+ - uses: actions/setup-java@v5
+ with:
+ cache: maven
+ distribution: temurin
+ java-version: 17
+ server-id: ossindex
+ server-username: OSSINDEX_USERNAME
+ server-password: OSSINDEX_TOKEN
+ - name: Ossindex
+ if: ${{ env.OSSINDEX_USERNAME != null && env.OSSINDEX_TOKEN != null }}
+ run: |
+ mvn --errors --batch-mode test-compile \
+ org.sonatype.ossindex.maven:ossindex-maven-plugin:audit \
+ org.sonatype.ossindex.maven:ossindex-maven-plugin:audit-aggregate
+ env:
+ OSSINDEX_USERNAME: ${{ secrets.OSSINDEX_USERNAME }}
+ OSSINDEX_TOKEN: ${{ secrets.OSSINDEX_TOKEN }}
+
+ build:
+ needs:
+ - matrix-build
+ - ossindex
+ runs-on: ubuntu-slim
+ permissions:
+ contents: read
steps:
- run: echo "Build successful"
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 522d768..7149f2e 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -5,8 +5,6 @@ on:
branches: [ main ]
pull_request:
branches: [ main ]
- schedule:
- - cron: '0 4 * * 3'
jobs:
analyze:
@@ -22,7 +20,9 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
- uses: actions/setup-java@v5
with:
@@ -35,8 +35,9 @@ jobs:
with:
languages: java
- - name: Autobuild
- uses: github/codeql-action/autobuild@v4
+ - name: Build
+ # gitcommitid plugin requires a newer version of maven, so we skip it here
+ run: mvn --batch-mode --errors -Dmaven.gitcommitid.skip=true clean compile
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 1ede7c9..d80b233 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -8,6 +8,11 @@ on:
required: true
type: boolean
default: false
+ maven-central-auto-publish:
+ description: "Automatically publish to Maven Central"
+ required: true
+ type: boolean
+ default: true
jobs:
release:
@@ -22,7 +27,9 @@ jobs:
contents: write # Required for creating GitHub release
steps:
- name: Checkout
- uses: actions/checkout@v5
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: true
- name: Fail if not running on main branch
if: ${{ github.ref != 'refs/heads/main' }}
@@ -37,25 +44,31 @@ jobs:
distribution: "temurin"
java-version: 17
cache: "maven"
- server-id: ossrh
+ server-id: central
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
gpg-private-key: ${{ secrets.OSSRH_GPG_SECRET_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE
- name: Build
- run: mvn --batch-mode -T 1C clean install
+ run: mvn --batch-mode -T 1C clean install -DossindexSkip=true
- name: List secret GPG keys
run: gpg --list-secret-keys
- name: Publish to Maven Central Repository
if: ${{ !inputs.skip-deploy-maven-central }}
- run: mvn --batch-mode deploy -DskipTests -Possrh -DstagingDescription="Deployed via GitHub workflow release.yml"
+ run: |
+ mvn --batch-mode deploy -DskipTests -PcentralPublishing
+ -DossindexSkip=true \
+ -DcentralPublishingDeploymentName="Deployed OFT Asciidoc Plugin via release.yml" \
+ -DcentralPublishingSkipPublishing=false \
+ -DcentralPublishingAutoPublish=${AUTO_PUBLISH}
env:
- MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
- MAVEN_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
+ MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_PORTAL_USERNAME }}
+ MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PORTAL_TOKEN }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }}
+ AUTO_PUBLISH: ${{ inputs.maven-central-auto-publish }}
- name: Create GitHub Release
run: ./.github/workflows/github_release.sh
diff --git a/.vscode/settings.json b/.vscode/settings.json
index b1f2fae..4f07762 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -6,7 +6,6 @@
"source.generate.finalModifiers": "explicit",
"source.fixAll": "explicit"
},
- "java.saveActions.organizeImports": true,
"java.sources.organizeImports.starThreshold": 3,
"java.sources.organizeImports.staticStarThreshold": 3,
"java.configuration.updateBuildConfiguration": "automatic",
diff --git a/doc/changes/changelog.md b/doc/changes/changelog.md
index 37d88fc..5cd0804 100644
--- a/doc/changes/changelog.md
+++ b/doc/changes/changelog.md
@@ -3,3 +3,4 @@
* [0.1.0](changes_0.1.0.md)
* [0.2.0](changes_0.2.0.md)
* [0.3.0](changes_0.3.0.md)
+* [0.3.1](changes_0.3.1.md)
diff --git a/doc/changes/changes_0.3.1.md b/doc/changes/changes_0.3.1.md
new file mode 100644
index 0000000..dce6486
--- /dev/null
+++ b/doc/changes/changes_0.3.1.md
@@ -0,0 +1,11 @@
+# OpenFastTrace AsciiDoc Plugin 0.3.1, released 2026-05-15
+
+Code name: Update Maven Central publishing
+
+## Summary
+
+This release updates dependencies and uses the new Maven Central Portal publishing process. The release also updates dependencies.
+
+## Bug Fixes
+
+* [PR #18](https://github.com/itsallcode/openfasttrace-asciidoc-plugin/pull/18): Updated dependencies
diff --git a/pom.xml b/pom.xml
index c220f80..7a691e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
org.itsallcode
openfasttrace-asciidoc-plugin
- 0.3.0
+ 0.3.1
jar
OpenFastTrace AsciiDoc Importer
@@ -15,13 +15,15 @@
UTF-8
17
- 4.1.0
- 5.11.4
- 0.8.12
+ 4.4.0
+ 6.0.3
+ 0.8.14
+
3.0.0
itsallcode
https://sonarcloud.io
${git.commit.time}
+ false
@@ -62,17 +64,6 @@
https://github.com/itsallcode/openfasttrace-asciidoc-plugin
-
-
- ossrh
- https://oss.sonatype.org/content/repositories/snapshots
-
-
- ossrh
- https://oss.sonatype.org/service/local/staging/deploy/maven2/
-
-
-
org.asciidoctor
@@ -107,14 +98,14 @@
org.junit.jupiter
- junit-jupiter-params
+ junit-jupiter
${junit.version}
test
org.mockito
mockito-junit-jupiter
- 5.12.0
+ 5.23.0
test
@@ -128,24 +119,31 @@
- ossrh
+ centralPublishing
+
+ false
+ false
+ Manual deployment of OFT Asciidoc Plugin
+
- org.sonatype.plugins
- nexus-staging-maven-plugin
- 1.7.0
+ org.sonatype.central
+ central-publishing-maven-plugin
+ 0.10.0
true
- ossrh
- https://oss.sonatype.org/
- true
+ central
+ ${centralPublishingSkipPublishing}
+ ${centralPublishingAutoPublish}
+ validated
+ ${centralPublishingDeploymentName}
org.apache.maven.plugins
maven-gpg-plugin
- 3.2.4
+ 3.2.8
sign-artifacts
@@ -159,7 +157,7 @@
org.apache.maven.plugins
maven-deploy-plugin
- 3.1.2
+ 3.1.4
@@ -171,7 +169,7 @@
io.github.git-commit-id
git-commit-id-maven-plugin
- 9.0.1
+ 10.0.0
get-the-git-infos
@@ -212,7 +210,7 @@
org.apache.maven.plugins
maven-enforcer-plugin
- 3.5.0
+ 3.6.2
enforce-maven
@@ -232,12 +230,12 @@
org.apache.maven.plugins
maven-clean-plugin
- 3.4.0
+ 3.5.0
org.apache.maven.plugins
maven-compiler-plugin
- 3.13.0
+ 3.15.0
${java.version}
${java.version}
@@ -251,12 +249,12 @@
org.apache.maven.plugins
maven-jar-plugin
- 3.4.2
+ 3.5.0
org.apache.maven.plugins
maven-source-plugin
- 3.3.1
+ 3.4.0
attach-sources
@@ -269,7 +267,7 @@
org.apache.maven.plugins
maven-javadoc-plugin
- 3.8.0
+ 3.12.0
attach-javadocs
@@ -289,7 +287,7 @@
org.apache.maven.plugins
maven-shade-plugin
- 3.6.0
+ 3.6.2
package
@@ -349,23 +347,39 @@
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.10.0
+
+
+
+ properties
+
+
+
org.apache.maven.plugins
maven-surefire-plugin
- 3.5.2
+ 3.5.5
src/test/resources/logging.properties
- -XX:+EnableDynamicAgentLoading ${argLine}
+ @{argLine} -javaagent:${org.mockito:mockito-core:jar}
org.sonatype.ossindex.maven
ossindex-maven-plugin
3.2.0
+
+ ossindex
+ ${ossindexSkip}
+
audit
@@ -404,7 +418,7 @@
org.apache.maven.plugins
maven-artifact-plugin
- 3.5.1
+ 3.6.1
verify-reproducible-build
@@ -416,6 +430,11 @@
true
+
+ org.sonarsource.scanner.maven
+ sonar-maven-plugin
+ 5.6.0.6792
+
diff --git a/src/test/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporterFactoryTest.java b/src/test/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporterFactoryTest.java
index fa15a89..5827c68 100644
--- a/src/test/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporterFactoryTest.java
+++ b/src/test/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporterFactoryTest.java
@@ -7,7 +7,7 @@
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
-public class AsciiDocImporterFactoryTest
+class AsciiDocImporterFactoryTest
{
// [utest->dsn~asciidoc-file-extensions~1]
@Test
diff --git a/src/test/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporterTest.java b/src/test/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporterTest.java
index 4e67fce..8400825 100644
--- a/src/test/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporterTest.java
+++ b/src/test/java/org/itsallcode/openfasttrace/importer/asciidoc/AsciiDocImporterTest.java
@@ -2,7 +2,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.*;
import org.itsallcode.openfasttrace.api.core.SpecificationItemId;
import org.itsallcode.openfasttrace.api.importer.ImportEventListener;
@@ -11,205 +11,200 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
-import org.mockito.*;
+import org.mockito.InOrder;
+import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
-public class AsciiDocImporterTest
+class AsciiDocImporterTest
{
- @Mock
- private ImportEventListener listener;
- private InOrder inOrder;
-
- @BeforeEach
- void setup()
- {
- inOrder = inOrder(listener);
- }
-
- @ParameterizedTest
- @ValueSource(strings =
- {
- """
- # Spec
-
- [.specitem]
- ## A Requirement
- """,
- """
- # Spec
-
- [.specitem]
- ====
- ====
- """
- })
- void testImporterIgnoresSpecItemWithoutId(final String content)
- {
- final var importer = new AsciiDocImporter(content, listener);
- importer.runImport();
- Mockito.verifyNoMoreInteractions(listener);
- }
-
- // [utest->dsn~adoc-specification-item-markup~1]
- // [utest->dsn~adoc-specification-item-id~1]
- // [utest->dsn~adoc-specification-item-title~1]
- // [utest->dsn~adoc-specification-item-description~1]
- // [utest->dsn~adoc-specification-item-rationale~1]
- // [utest->dsn~adoc-specification-item-comment~1]
- // [utest->dsn~adoc-depends-list~1]
- // [utest->dsn~adoc-covers-list~1]
- // [utest->dsn~adoc-needs-coverage-list~1]
- @ParameterizedTest
- @ValueSource(strings =
- {
- """
- # Spec
-
- [.specitem, oft-sid="dsn~detail-design~1", oft-depends="dsn~grand-design~1, arch~general-constraints~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1, req~second-requirement~1", oft-tags="Priority1, OtherComponent"]
- ## A Requirement
-
- The description
-
- [.rationale]
- The rationale
-
- [.comment]
- A comment
- """,
- """
- # Spec
-
- [.specitem, oft-sid="dsn~detail-design~1", oft-depends="dsn~grand-design~1, arch~general-constraints~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1, req~second-requirement~1", oft-tags="Priority1, OtherComponent"]
- ## A Requirement
-
- [.rationale]
- The rationale
-
- [.description]
- The description
-
- [.comment]
- A comment
- """,
- """
- # Spec
-
- .A Requirement
- [.specitem, oft-sid="dsn~detail-design~1", oft-depends="dsn~grand-design~1, arch~general-constraints~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1, req~second-requirement~1", oft-tags="Priority1, OtherComponent"]
- ====
-
- The description
-
- [.rationale]
- The rationale
-
- [.comment]
- A comment
- ====
- """,
- """
- # Spec
-
- .A Requirement
- [.specitem, oft-sid="dsn~detail-design~1", oft-depends="dsn~grand-design~1, arch~general-constraints~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1, req~second-requirement~1", oft-tags="Priority1, OtherComponent"]
- ====
-
- [.rationale]
- The rationale
-
- [.description]
- The description
-
- [.comment]
- A comment
- ====
- """
- })
- void testImporterReadsFullSpecItem(final String content)
- {
- final var importer = new AsciiDocImporter(content, listener);
- importer.runImport();
- inOrder.verify(listener).beginSpecificationItem();
- Mockito.verify(listener).setId(new SpecificationItemId.Builder("dsn~detail-design~1").build());
- Mockito.verify(listener).setLocation(any());
- Mockito.verify(listener).setTitle("A Requirement");
- Mockito.verify(listener).addDependsOnId(new SpecificationItemId.Builder("dsn~grand-design~1").build());
- Mockito.verify(listener)
- .addDependsOnId(new SpecificationItemId.Builder("arch~general-constraints~1").build());
- Mockito.verify(listener).addNeededArtifactType("impl");
- Mockito.verify(listener).addNeededArtifactType("utest");
- Mockito.verify(listener)
- .addCoveredId(new SpecificationItemId.Builder("req~first-requirement~1").build());
- Mockito.verify(listener)
- .addCoveredId(new SpecificationItemId.Builder("req~second-requirement~1").build());
- Mockito.verify(listener).addTag("Priority1");
- Mockito.verify(listener).addTag("OtherComponent");
- Mockito.verify(listener).appendDescription("The description");
- Mockito.verify(listener).appendRationale("The rationale");
- Mockito.verify(listener).appendComment("A comment");
- inOrder.verify(listener).endSpecificationItem();
- Mockito.verifyNoMoreInteractions(listener);
- }
-
- // [utest->dsn~adoc-artifact-forwarding-notation~1]
- @Test
- void testImporterReadsForwardingSpecItem()
- {
- final var content = """
- # Spec
-
- ## Design
-
- [.specitem, oft-skipped="dsn", oft-needs="impl, utest", oft-covers="req~first-requirement~1"]
- --
- --
- """;
- final var importer = new AsciiDocImporter(content, listener);
- importer.runImport();
- inOrder.verify(listener).beginSpecificationItem();
- Mockito.verify(listener)
- .setId(new SpecificationItemId.Builder("dsn~first-requirement~1").build());
- Mockito.verify(listener).setLocation(
- argThat(location -> "verbatim".equals(location.getPath()) && location.getLine() == 6));
- Mockito.verify(listener).addNeededArtifactType("impl");
- Mockito.verify(listener).addNeededArtifactType("utest");
- Mockito.verify(listener)
- .addCoveredId(new SpecificationItemId.Builder("req~first-requirement~1").build());
- inOrder.verify(listener).endSpecificationItem();
- Mockito.verifyNoMoreInteractions(listener);
- }
-
- @Test
- void testImporterReadsSpecItemNestedInTableCell()
- {
- final var content = """
- .Test Table
- [%autowidth]
- |===
- |Column 1 |Column 2
-
- |Default Style
- a|
- Asciidoc Style
-
- [.specitem, oft-sid="req~nested-in-table~1", oft-needs="dsn"]
- --
- The description
- --
- |===
- """;
- final var importer = new AsciiDocImporter(content, listener);
- importer.runImport();
- inOrder.verify(listener).beginSpecificationItem();
- Mockito.verify(listener)
- .setId(new SpecificationItemId.Builder("req~nested-in-table~1").build());
- Mockito.verify(listener).setLocation(
- argThat(location -> "verbatim".equals(location.getPath())));
- Mockito.verify(listener).addNeededArtifactType("dsn");
- Mockito.verify(listener).appendDescription("The description");
- inOrder.verify(listener).endSpecificationItem();
- Mockito.verifyNoMoreInteractions(listener);
- }
-
+ @Mock
+ private ImportEventListener listener;
+ private InOrder inOrder;
+
+ @BeforeEach
+ void setup()
+ {
+ inOrder = inOrder(listener);
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings =
+ {
+ """
+ # Spec
+
+ [.specitem]
+ ## A Requirement
+ """,
+ """
+ # Spec
+
+ [.specitem]
+ ====
+ ====
+ """
+ })
+ void testImporterIgnoresSpecItemWithoutId(final String content)
+ {
+ final var importer = new AsciiDocImporter(content, listener);
+ importer.runImport();
+ verifyNoMoreInteractions(listener);
+ }
+
+ // [utest->dsn~adoc-specification-item-markup~1]
+ // [utest->dsn~adoc-specification-item-id~1]
+ // [utest->dsn~adoc-specification-item-title~1]
+ // [utest->dsn~adoc-specification-item-description~1]
+ // [utest->dsn~adoc-specification-item-rationale~1]
+ // [utest->dsn~adoc-specification-item-comment~1]
+ // [utest->dsn~adoc-depends-list~1]
+ // [utest->dsn~adoc-covers-list~1]
+ // [utest->dsn~adoc-needs-coverage-list~1]
+ @ParameterizedTest
+ @ValueSource(strings =
+ {
+ """
+ # Spec
+
+ [.specitem, oft-sid="dsn~detail-design~1", oft-depends="dsn~grand-design~1, arch~general-constraints~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1, req~second-requirement~1", oft-tags="Priority1, OtherComponent"]
+ ## A Requirement
+
+ The description
+
+ [.rationale]
+ The rationale
+
+ [.comment]
+ A comment
+ """,
+ """
+ # Spec
+
+ [.specitem, oft-sid="dsn~detail-design~1", oft-depends="dsn~grand-design~1, arch~general-constraints~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1, req~second-requirement~1", oft-tags="Priority1, OtherComponent"]
+ ## A Requirement
+
+ [.rationale]
+ The rationale
+
+ [.description]
+ The description
+
+ [.comment]
+ A comment
+ """,
+ """
+ # Spec
+
+ .A Requirement
+ [.specitem, oft-sid="dsn~detail-design~1", oft-depends="dsn~grand-design~1, arch~general-constraints~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1, req~second-requirement~1", oft-tags="Priority1, OtherComponent"]
+ ====
+
+ The description
+
+ [.rationale]
+ The rationale
+
+ [.comment]
+ A comment
+ ====
+ """,
+ """
+ # Spec
+
+ .A Requirement
+ [.specitem, oft-sid="dsn~detail-design~1", oft-depends="dsn~grand-design~1, arch~general-constraints~1", oft-needs="impl, utest", oft-covers="req~first-requirement~1, req~second-requirement~1", oft-tags="Priority1, OtherComponent"]
+ ====
+
+ [.rationale]
+ The rationale
+
+ [.description]
+ The description
+
+ [.comment]
+ A comment
+ ====
+ """
+ })
+ void testImporterReadsFullSpecItem(final String content)
+ {
+ final var importer = new AsciiDocImporter(content, listener);
+ importer.runImport();
+ inOrder.verify(listener).beginSpecificationItem();
+ verify(listener).setId(new SpecificationItemId.Builder("dsn~detail-design~1").build());
+ verify(listener).setLocation(any());
+ verify(listener).setTitle("A Requirement");
+ verify(listener).addDependsOnId(new SpecificationItemId.Builder("dsn~grand-design~1").build());
+ verify(listener).addDependsOnId(new SpecificationItemId.Builder("arch~general-constraints~1").build());
+ verify(listener).addNeededArtifactType("impl");
+ verify(listener).addNeededArtifactType("utest");
+ verify(listener).addCoveredId(new SpecificationItemId.Builder("req~first-requirement~1").build());
+ verify(listener).addCoveredId(new SpecificationItemId.Builder("req~second-requirement~1").build());
+ verify(listener).addTag("Priority1");
+ verify(listener).addTag("OtherComponent");
+ verify(listener).appendDescription("The description");
+ verify(listener).appendRationale("The rationale");
+ verify(listener).appendComment("A comment");
+ inOrder.verify(listener).endSpecificationItem();
+ verifyNoMoreInteractions(listener);
+ }
+
+ // [utest->dsn~adoc-artifact-forwarding-notation~1]
+ @Test
+ void testImporterReadsForwardingSpecItem()
+ {
+ final var content = """
+ # Spec
+
+ ## Design
+
+ [.specitem, oft-skipped="dsn", oft-needs="impl, utest", oft-covers="req~first-requirement~1"]
+ --
+ --
+ """;
+ final var importer = new AsciiDocImporter(content, listener);
+ importer.runImport();
+ inOrder.verify(listener).beginSpecificationItem();
+ verify(listener).setId(new SpecificationItemId.Builder("dsn~first-requirement~1").build());
+ verify(listener).setLocation(
+ argThat(location -> "verbatim".equals(location.getPath()) && location.getLine() == 6));
+ verify(listener).addNeededArtifactType("impl");
+ verify(listener).addNeededArtifactType("utest");
+ verify(listener).addCoveredId(new SpecificationItemId.Builder("req~first-requirement~1").build());
+ inOrder.verify(listener).endSpecificationItem();
+ verifyNoMoreInteractions(listener);
+ }
+
+ @Test
+ void testImporterReadsSpecItemNestedInTableCell()
+ {
+ final var content = """
+ .Test Table
+ [%autowidth]
+ |===
+ |Column 1 |Column 2
+
+ |Default Style
+ a|
+ Asciidoc Style
+
+ [.specitem, oft-sid="req~nested-in-table~1", oft-needs="dsn"]
+ --
+ The description
+ --
+ |===
+ """;
+ final var importer = new AsciiDocImporter(content, listener);
+ importer.runImport();
+ inOrder.verify(listener).beginSpecificationItem();
+ verify(listener)
+ .setId(new SpecificationItemId.Builder("req~nested-in-table~1").build());
+ verify(listener).setLocation(
+ argThat(location -> "verbatim".equals(location.getPath())));
+ verify(listener).addNeededArtifactType("dsn");
+ verify(listener).appendDescription("The description");
+ inOrder.verify(listener).endSpecificationItem();
+ verifyNoMoreInteractions(listener);
+ }
}