From 5968b90a7c9bb054d2651ddf88f511b0fbc540cd Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Sun, 5 Jan 2025 12:49:11 +0100 Subject: [PATCH 1/8] #280: Inside Markdown code blocks requirements are now ignored. --- .../statemachine/LineParserState.java | 2 ++ .../importer/markdown/MarkdownImporter.java | 6 ++-- .../importer/markdown/MdPattern.java | 2 ++ .../markdown/TestMarkdownMarkupImporter.java | 34 +++++++++++++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/statemachine/LineParserState.java b/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/statemachine/LineParserState.java index 7bd3cc73..649eba11 100644 --- a/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/statemachine/LineParserState.java +++ b/importer/lightweightmarkup/src/main/java/org/itsallcode/openfasttrace/importer/lightweightmarkup/statemachine/LineParserState.java @@ -29,6 +29,8 @@ public enum LineParserState TITLE, /** Found tags */ TAGS, + /** Code block */ + CODE_BLOCK, /** Reached the end of the file */ EOF } diff --git a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java index 4014375b..586eb113 100644 --- a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java +++ b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MarkdownImporter.java @@ -42,6 +42,7 @@ protected Transition[] configureTransitions() transition(START , SPEC_ITEM , MdPattern.ID , this::beginItem ), transition(START , TITLE , SECTION_TITLE , this::rememberTitle ), transition(START , START , MdPattern.FORWARD , this::forward ), + transition(START , CODE_BLOCK , MdPattern.CODE_BEGIN , () -> {} ), transition(START , START , MdPattern.EVERYTHING , () -> {} ), transition(TITLE , SPEC_ITEM , MdPattern.ID , this::beginItem ), @@ -99,7 +100,6 @@ protected Transition[] configureTransitions() transition(COMMENT , TAGS , MdPattern.TAGS , () -> {} ), transition(COMMENT , COMMENT , MdPattern.EVERYTHING , this::appendComment ), - // [impl->dsn~md.covers-list~1] transition(COVERS , SPEC_ITEM , MdPattern.ID , this::beginItem ), transition(COVERS , TITLE , SECTION_TITLE , () -> {endItem(); rememberTitle();}), @@ -156,7 +156,9 @@ protected Transition[] configureTransitions() transition(TAGS , COVERS , MdPattern.COVERS , () -> {} ), transition(TAGS , TAGS , MdPattern.TAGS , () -> {} ), transition(TAGS , TAGS , MdPattern.TAGS_INT , this::addTag ), - transition(TAGS , START , MdPattern.FORWARD , () -> {endItem(); forward();} ) + transition(TAGS , START , MdPattern.FORWARD , () -> {endItem(); forward();} ), + + transition(CODE_BLOCK , START , MdPattern.CODE_END , () -> {} ) }; // @formatter:on } diff --git a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MdPattern.java b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MdPattern.java index b5cd0c4c..510e9f4e 100644 --- a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MdPattern.java +++ b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MdPattern.java @@ -15,6 +15,8 @@ enum MdPattern // [impl->dsn~md.artifact-forwarding-notation~1] // @formatter:off + CODE_BEGIN("```\\w*\\s*"), + CODE_END("```"), COMMENT("Comment:\\s*"), COVERS("Covers:\\s*"), COVERS_REF(PatternConstants.REFERENCE_AFTER_BULLET), diff --git a/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java b/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java index 671435e6..fbb51dcc 100644 --- a/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java +++ b/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java @@ -3,6 +3,7 @@ import static org.itsallcode.matcher.auto.AutoMatcher.contains; import static org.itsallcode.openfasttrace.testutil.core.ItemBuilderFactory.item; +import org.hamcrest.Matchers; import org.itsallcode.openfasttrace.api.core.SpecificationItemId; import org.itsallcode.openfasttrace.api.importer.ImporterFactory; import org.itsallcode.openfasttrace.testutil.importer.lightweightmarkup.AbstractLightWeightMarkupImporterTest; @@ -138,4 +139,37 @@ void testLessThenThreeUnderliningCharactersAreNotDetectedAsTitleUnderlines() .location("z", 3) .build())); } + + @Test + void testWhenInsideMarkdownCodeBlockThenNoSpecificationItemMustBeDetected() { + assertImport("file_with_code_block.md", """ + ``` + This is a code block, the following requirement must be ignored. + + req~example~1 + ``` + """, + Matchers.emptyIterable()); + } + + // Unit Test + @Test + void testWhenCodeBlockIsInsideCommentSectionThenItIsImportedAsPartOfComment() { + assertImport("file_with_code_block_in_comment.md", """ + req~comment_with_code_block~1 + Comment: + + ``` + This is a code block inside a comment. + ``` + """, + contains(item() + .id(SpecificationItemId.createId("req", "comment_with_code_block", 1)) + .comment(""" + ``` + This is a code block inside a comment. + ```""") + .location("file_with_code_block_in_comment.md", 1) + .build())); + } } From bb54b0cb42e4a79211b46915aec79731cd2e08fc Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Sun, 5 Jan 2025 12:54:37 +0100 Subject: [PATCH 2/8] #280: Inside Markdown code blocks requirements are now ignored. --- doc/changes/changes.md | 1 + doc/changes/changes_4.2.0.md | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 doc/changes/changes_4.2.0.md diff --git a/doc/changes/changes.md b/doc/changes/changes.md index 9f618092..eea7a754 100644 --- a/doc/changes/changes.md +++ b/doc/changes/changes.md @@ -1,5 +1,6 @@ # Changes +* [4.2.0](changes_4.2.0.md) * [4.1.0](changes_4.1.0.md) * [4.0.2](changes_4.0.2.md) * [4.0.1](changes_4.0.1.md) diff --git a/doc/changes/changes_4.2.0.md b/doc/changes/changes_4.2.0.md new file mode 100644 index 00000000..69f7dca0 --- /dev/null +++ b/doc/changes/changes_4.2.0.md @@ -0,0 +1,11 @@ +# OpenFastTrace 4.2.0, released ??? + +Code name: Markdown code blocks + +## Summary + +In this release we changed the behavior of the Markdown importer, so that if we are inside a code block, no OFT specification items are found. This is a corner case, but we think that this behavior is what users would expect (#480). + +## Features + +* #480: Ignore specification items inside Markdown code blocks From 3233979669c0f32d9f05b9a86955fa5ce1ccb73a Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Mon, 6 Jan 2025 13:16:32 +0100 Subject: [PATCH 3/8] #280: Added test for different start or end markers. --- .../markdown/TestMarkdownMarkupImporter.java | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java b/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java index fbb51dcc..37d63c51 100644 --- a/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java +++ b/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java @@ -1,14 +1,15 @@ package org.itsallcode.openfasttrace.importer.markdown; +import static org.hamcrest.Matchers.emptyIterable; import static org.itsallcode.matcher.auto.AutoMatcher.contains; import static org.itsallcode.openfasttrace.testutil.core.ItemBuilderFactory.item; -import org.hamcrest.Matchers; import org.itsallcode.openfasttrace.api.core.SpecificationItemId; import org.itsallcode.openfasttrace.api.importer.ImporterFactory; import org.itsallcode.openfasttrace.testutil.importer.lightweightmarkup.AbstractLightWeightMarkupImporterTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; class TestMarkdownMarkupImporter extends AbstractLightWeightMarkupImporterTest @@ -140,25 +141,36 @@ void testLessThenThreeUnderliningCharactersAreNotDetectedAsTitleUnderlines() .build())); } - @Test - void testWhenInsideMarkdownCodeBlockThenNoSpecificationItemMustBeDetected() { + @ParameterizedTest + @CsvSource( + { + "```,```", + "``` ,``` ", + "``` ,```", + "```java, ```", + "```java , ``` ", + }) + void testWhenInsideMarkdownCodeBlockThenNoSpecificationItemMustBeDetected(final String startMarker, + final String endMarker) + { assertImport("file_with_code_block.md", """ - ``` - This is a code block, the following requirement must be ignored. - - req~example~1 - ``` - """, - Matchers.emptyIterable()); + %s + This is a code block, the following requirement must be ignored. + + req~example~1 + %s + """.formatted(startMarker, endMarker), + emptyIterable()); } // Unit Test @Test - void testWhenCodeBlockIsInsideCommentSectionThenItIsImportedAsPartOfComment() { + void testWhenCodeBlockIsInsideCommentSectionThenItIsImportedAsPartOfComment() + { assertImport("file_with_code_block_in_comment.md", """ req~comment_with_code_block~1 Comment: - + ``` This is a code block inside a comment. ``` From 6182701488d90e11c56e79635beb4f109c9a7101 Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Mon, 6 Jan 2025 13:28:43 +0100 Subject: [PATCH 4/8] #280: Added more allowed variants for code block start and end tags (see https://github.github.com/gfm/#fenced-code-blocks for specification). --- .../openfasttrace/importer/markdown/MdPattern.java | 4 ++-- .../importer/markdown/TestMarkdownMarkupImporter.java | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MdPattern.java b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MdPattern.java index 510e9f4e..5e848b63 100644 --- a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MdPattern.java +++ b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MdPattern.java @@ -15,8 +15,8 @@ enum MdPattern // [impl->dsn~md.artifact-forwarding-notation~1] // @formatter:off - CODE_BEGIN("```\\w*\\s*"), - CODE_END("```"), + CODE_BEGIN(" {0,3}[`~]{3,30}\\w*\\s*"), + CODE_END(" {0,3}[`~]{3,30}\\s*"), COMMENT("Comment:\\s*"), COVERS("Covers:\\s*"), COVERS_REF(PatternConstants.REFERENCE_AFTER_BULLET), diff --git a/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java b/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java index 37d63c51..67d66a56 100644 --- a/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java +++ b/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java @@ -147,8 +147,15 @@ void testLessThenThreeUnderliningCharactersAreNotDetectedAsTitleUnderlines() "```,```", "``` ,``` ", "``` ,```", + "````, ````", + " ```, ```", + " ```, ```", + " ```, ```", "```java, ```", "```java , ``` ", + "~~~, ~~~", + "~~~java, ~~~", + " ~~~~java, ~~~~ " }) void testWhenInsideMarkdownCodeBlockThenNoSpecificationItemMustBeDetected(final String startMarker, final String endMarker) From 290b2284c54ea047f3ef6869b2f96f88f1aa5e8f Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Mon, 6 Jan 2025 19:12:02 +0100 Subject: [PATCH 5/8] #431: Allow deeper indentation. In case parent block is already indented. --- .../itsallcode/openfasttrace/importer/markdown/MdPattern.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MdPattern.java b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MdPattern.java index 5e848b63..27962554 100644 --- a/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MdPattern.java +++ b/importer/markdown/src/main/java/org/itsallcode/openfasttrace/importer/markdown/MdPattern.java @@ -15,8 +15,8 @@ enum MdPattern // [impl->dsn~md.artifact-forwarding-notation~1] // @formatter:off - CODE_BEGIN(" {0,3}[`~]{3,30}\\w*\\s*"), - CODE_END(" {0,3}[`~]{3,30}\\s*"), + CODE_BEGIN(" *[`~]{3,30}\\w*\\s*"), + CODE_END(" *[`~]{3,30}\\s*"), COMMENT("Comment:\\s*"), COVERS("Covers:\\s*"), COVERS_REF(PatternConstants.REFERENCE_AFTER_BULLET), From d64456d09a70124e5557104c95cd90dbbebbd2bc Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Mon, 6 Jan 2025 19:17:03 +0100 Subject: [PATCH 6/8] #431: Added bad weather test scenario. --- .../markdown/TestMarkdownMarkupImporter.java | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java b/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java index 67d66a56..7e24559d 100644 --- a/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java +++ b/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java @@ -161,16 +161,47 @@ void testWhenInsideMarkdownCodeBlockThenNoSpecificationItemMustBeDetected(final final String endMarker) { assertImport("file_with_code_block.md", """ - %s - This is a code block, the following requirement must be ignored. + %s + This is a code block, the following requirement must be ignored. - req~example~1 - %s - """.formatted(startMarker, endMarker), + req~example~1 + %s + """.formatted(startMarker, endMarker), emptyIterable()); } - // Unit Test + @ParameterizedTest + @CsvSource( + { + "'', ''", + "', '", + "'`', '`'", + "'``', '``'", + "'````', '````'", + "'``` ', ' ```'", + "'``` ', ' ```'", + "' ```', '``` '", + "'```java ', ' ```java'", + "'~~~', '~~~'", + "'~~~java', '~~~java'", + "'~~~~java ', ' ~~~~java '" + }) + void testWhenNotInsideMarkdownCodeBlockThenSpecificationItemMustBeDetected(final String startMarker, + final String endMarker) + { + assertImport("file_without_code_block.md", """ + %s + This is not a code block, the following requirement must be detected. + + req~example~1 + %s + """.formatted(startMarker, endMarker), + contains(item() + .id(SpecificationItemId.parseId("req~example~1")) + .location("file_without_code_block.md", 4) + .build())); + } + @Test void testWhenCodeBlockIsInsideCommentSectionThenItIsImportedAsPartOfComment() { From 22ab6b00e16d3c6879fd92ab36e1ccc8ac8aa85c Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Mon, 6 Jan 2025 19:27:36 +0100 Subject: [PATCH 7/8] #431: Added bad weather test scenario. --- .../markdown/TestMarkdownMarkupImporter.java | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java b/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java index 7e24559d..b8a11c36 100644 --- a/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java +++ b/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java @@ -173,18 +173,12 @@ void testWhenInsideMarkdownCodeBlockThenNoSpecificationItemMustBeDetected(final @ParameterizedTest @CsvSource( { - "'', ''", - "', '", - "'`', '`'", - "'``', '``'", - "'````', '````'", - "'``` ', ' ```'", - "'``` ', ' ```'", - "' ```', '``` '", - "'```java ', ' ```java'", - "'~~~', '~~~'", - "'~~~java', '~~~java'", - "'~~~~java ', ' ~~~~java '" + "`,`", + "``,``", + " ``', ``", + "`` ,`` ", + "``java,``", + "~~,~~", }) void testWhenNotInsideMarkdownCodeBlockThenSpecificationItemMustBeDetected(final String startMarker, final String endMarker) @@ -199,6 +193,7 @@ void testWhenNotInsideMarkdownCodeBlockThenSpecificationItemMustBeDetected(final contains(item() .id(SpecificationItemId.parseId("req~example~1")) .location("file_without_code_block.md", 4) + .description(endMarker) // End marker looks like part of the description in this case. .build())); } From 84c1dd0cec9e6673dbb6a6abe6af01dfa68c771a Mon Sep 17 00:00:00 2001 From: redcatbaer Date: Mon, 6 Jan 2025 20:02:01 +0100 Subject: [PATCH 8/8] #431: Made test pass on Windows.. --- .../importer/markdown/TestMarkdownMarkupImporter.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java b/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java index b8a11c36..c967840d 100644 --- a/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java +++ b/importer/markdown/src/test/java/org/itsallcode/openfasttrace/importer/markdown/TestMarkdownMarkupImporter.java @@ -210,10 +210,8 @@ void testWhenCodeBlockIsInsideCommentSectionThenItIsImportedAsPartOfComment() """, contains(item() .id(SpecificationItemId.createId("req", "comment_with_code_block", 1)) - .comment(""" - ``` - This is a code block inside a comment. - ```""") + .comment("```" + System.lineSeparator()+ "This is a code block inside a comment." + + System.lineSeparator() + "```") .location("file_with_code_block_in_comment.md", 1) .build())); }