|
| 1 | +# GH-563 Support Gherkin `.feature` Files As OpenFastTrace Specification Documents |
| 2 | + |
| 3 | +## Goal |
| 4 | + |
| 5 | +Allow OpenFastTrace to import specification items from Gherkin `Scenario` and |
| 6 | +`Scenario Outline` blocks in `.feature` files. Preserve legacy coverage tags |
| 7 | +when they are written in Gherkin comments, while avoiding coverage-tag regular |
| 8 | +expression evaluation for executable Gherkin lines. |
| 9 | + |
| 10 | +## Scope |
| 11 | + |
| 12 | +In scope: |
| 13 | + |
| 14 | +* Extract shared line scanning and long/short coverage-tag parsing into a |
| 15 | + prerequisite module. |
| 16 | +* Add a dedicated Gherkin importer that composes the shared tag parser. |
| 17 | +* Import OFT scenario items identified by `@id:<oft-id>`. |
| 18 | +* Parse scoped `# Covers:` and `# Needs:` metadata strictly. |
| 19 | +* Preserve comment-based legacy coverage tags in `.feature` files and all |
| 20 | + existing tag importer behavior for non-`.feature` inputs. |
| 21 | +* Update traced requirements, design, tests, and user documentation. |
| 22 | + |
| 23 | +Out of scope: |
| 24 | + |
| 25 | +* Importing `Feature`, `Rule`, `Background`, or `Examples` as specification |
| 26 | + items. |
| 27 | +* Supporting coverage tags in executable Gherkin lines. |
| 28 | +* Adding an external Gherkin parser dependency. |
| 29 | +* Moving Gherkin grammar or validation into the shared parser module. |
| 30 | + |
| 31 | +## Design References |
| 32 | + |
| 33 | +* [System Requirements](../spec/system_requirements.md) |
| 34 | +* [Design](../spec/design.md) |
| 35 | +* [Quality Requirements](../spec/design/quality_requirements.md) |
| 36 | +* [User Guide](../user_guide.md) |
| 37 | + |
| 38 | +## Strategy |
| 39 | + |
| 40 | +1. Merge a behavior-preserving refactoring PR that introduces a shared module |
| 41 | + for line scanning and long/short coverage-tag parsing. It retains `.feature` |
| 42 | + support in the tag importer. |
| 43 | +2. Atomically move `.feature` ownership from the tag importer to a new Gherkin |
| 44 | + importer with higher precedence when the Gherkin importer is registered. |
| 45 | +3. Implement Gherkin parsing as a single-pass state machine. It receives every |
| 46 | + line but forwards only comment lines to the shared coverage-tag parser. |
| 47 | +4. Keep all Gherkin syntax, state, validation, and `ImportEventListener` |
| 48 | + mapping in the Gherkin importer. |
| 49 | + |
| 50 | +## Gherkin Syntax And Behavior |
| 51 | + |
| 52 | +* A Gherkin scenario is an OFT item only when its immediately preceding, |
| 53 | + contiguous Gherkin tag region contains exactly one |
| 54 | + `@id:<SpecificationItemId>` tag. Other Gherkin tags are ignored. |
| 55 | +* Directives are recognized only in `#` comment lines after that ID tag region |
| 56 | + and before the associated `Scenario:` or `Scenario Outline:` header. |
| 57 | + Comments elsewhere are ignored by Gherkin metadata parsing. |
| 58 | +* `# Covers:` and `# Needs:` are case-sensitive. Each is optional but may occur |
| 59 | + at most once. When present, it must contain a non-empty comma-separated list; |
| 60 | + duplicate values and malformed IDs or artifact types are errors. |
| 61 | +* A repeated or invalid `@id` tag, or a scoped directive without exactly one |
| 62 | + valid ID, fails the import with an `ImporterException` containing the file, |
| 63 | + line, and reason. Scenarios without OFT metadata remain ignored. |
| 64 | +* The scenario header line is the item location. Text after `Scenario:` or |
| 65 | + `Scenario Outline:` is the title. The importer streams the scenario-step |
| 66 | + block into the description, excluding comments and `Examples`; it ends the |
| 67 | + item at the next `Scenario`, `Scenario Outline`, `Feature`, `Rule`, |
| 68 | + `Background`, `Examples`, or end of file. |
| 69 | +* The importer retains only active metadata and previously imported Gherkin IDs |
| 70 | + for duplicate detection. It does not buffer a complete file or description. |
| 71 | + |
| 72 | +## Task List |
| 73 | + |
| 74 | +- [ ] Create and checkout branch |
| 75 | + `feature/563_support_gherkin_feature_specification_documents`. |
| 76 | + |
| 77 | +### PR 1: Shared Coverage-Tag Parser Refactoring |
| 78 | + |
| 79 | +- [ ] Add `importer/tag-importer-common` with artifact ID |
| 80 | + `openfasttrace-importer-tag-importer-common` to the Maven reactor. |
| 81 | +- [ ] Add JPMS module `org.itsallcode.openfasttrace.importer.tag.common` and |
| 82 | + export only `LineReader` (including its line-consumer contract) and |
| 83 | + `CoverageTagParser` from |
| 84 | + `org.itsallcode.openfasttrace.importer.tag.common`. |
| 85 | +- [ ] Move line scanning, line-handler composition, regex matching, long/short |
| 86 | + coverage-tag parsing, and CRC32 ID generation from `importer/tag` into |
| 87 | + the shared module without changing parsing semantics, generated IDs, |
| 88 | + listener events, logging, or exception wrapping. |
| 89 | +- [ ] Define `CoverageTagParser.create(PathConfig, InputFile, |
| 90 | + ImportEventListener)` to compose the long-tag parser and, when a path |
| 91 | + configuration is present, the short-tag parser into one line consumer. |
| 92 | + Keep parser implementation classes encapsulated. |
| 93 | +- [ ] Refactor `openfasttrace-importer-tag` into a thin adapter that creates |
| 94 | + the shared parser and scans its input once with the shared `LineReader`. |
| 95 | + Keep all supported extensions, including `.feature`, unchanged in this |
| 96 | + refactoring PR. |
| 97 | +- [ ] Move scanner tests to the shared module and add focused shared-parser |
| 98 | + tests for representative long and configured short tags, asserting |
| 99 | + listener events, locations, generated IDs, coverage links, and needed |
| 100 | + artifact types. |
| 101 | +- [ ] Keep the existing tag-importer parsing and factory/configuration tests as |
| 102 | + regression tests, including `.feature` support, to prove that the |
| 103 | + refactoring is behavior-preserving. |
| 104 | + |
| 105 | +### Requirements And Design |
| 106 | + |
| 107 | +- [ ] Add requirements for importing Gherkin scenarios and outlines, strict |
| 108 | + scoped metadata validation, Gherkin importer selection, and comment-only |
| 109 | + legacy coverage-tag compatibility. |
| 110 | +- [ ] Stop and ask user for review of the updated system requirements. |
| 111 | +- [ ] Add design items for factory precedence, the streaming Gherkin state |
| 112 | + machine, metadata scope, event mapping, and shared-parser delegation. |
| 113 | +- [ ] Stop and ask user for review of the updated design. |
| 114 | + |
| 115 | +### PR 2: Gherkin Importer |
| 116 | + |
| 117 | +- [ ] Add `importer/gherkin` with artifact ID |
| 118 | + `openfasttrace-importer-gherkin`; register it in the Maven reactor and |
| 119 | + product dependencies. |
| 120 | +- [ ] Provide a Gherkin importer factory for `.feature` files with priority |
| 121 | + `9000`, ahead of the tag importer's priority `10000`. |
| 122 | +- [ ] Implement the defined single-pass Gherkin state machine and map imported |
| 123 | + scenario fragments to `ImportEventListener` events. |
| 124 | +- [ ] Inject the shared coverage-tag parser and forward only lines whose |
| 125 | + trimmed form starts with `#` to it. |
| 126 | +- [ ] Implement the specified `@id:`, `Covers`, `Needs`, title, description, |
| 127 | + boundary, duplicate-ID, and error behavior. |
| 128 | +- [ ] Preserve the shared parser's existing `ImporterException` behavior for |
| 129 | + legacy coverage tags; do not introduce a new shared validation exception. |
| 130 | + |
| 131 | +### Verification |
| 132 | + |
| 133 | +- [ ] Add Gherkin importer unit tests for valid scenarios and outlines, |
| 134 | + location/title/description extraction, coverage metadata, non-OFT tags, |
| 135 | + and ignored ordinary scenarios. |
| 136 | +- [ ] Add validation tests for invalid or multiple IDs, orphan directives, |
| 137 | + repeated or empty directives, malformed list entries, duplicate metadata |
| 138 | + values, and duplicate Gherkin IDs. Assert exception type and relevant |
| 139 | + message content. |
| 140 | +- [ ] Add regression tests proving comment coverage tags import in `.feature` |
| 141 | + files, non-comment coverage-tag text is ignored in `.feature` files, and |
| 142 | + tag importer behavior for non-`.feature` inputs is unchanged. |
| 143 | +- [ ] Add pipeline tests proving each Gherkin file is scanned once and only |
| 144 | + comment lines reach the shared coverage-tag parser. |
| 145 | +- [ ] Add product-level tests for Gherkin importer precedence and mixed |
| 146 | + scenario specifications with comment-based legacy coverage tags. |
| 147 | +- [ ] Run `./oft-self-trace.sh` and ensure the trace stays clean. |
| 148 | +- [ ] Run `mvn -T 1C verify` and ensure all quality gates pass. |
| 149 | + |
| 150 | +### Documentation And Changelog |
| 151 | + |
| 152 | +- [ ] Extend [doc/user_guide.md](../user_guide.md) with the `.feature` syntax, |
| 153 | + placement rules, validation behavior, and examples. |
| 154 | +- [ ] Update [.agents/skills/openfasttrace/SKILL.md](../../.agents/skills/openfasttrace/SKILL.md) |
| 155 | + with the Gherkin syntax and comment-only compatibility rule. |
| 156 | +- [ ] Add the GH-563 entry to [doc/changes/changes_4.6.0.md](../changes/changes_4.6.0.md). |
0 commit comments