Skip to content

Commit

Permalink
#417: Allow numbers after dots in specificaiton item names (#418)
Browse files Browse the repository at this point in the history
Co-authored-by: Sebastian Bär <redcatbear@ursus-minor.de>
  • Loading branch information
kaklakariada and redcatbear authored Jun 22, 2024
1 parent 8c2c443 commit 63c846a
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 29 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ OpenFastTrace at it's core is a Java Archive (short "[JAR](https://docs.oracle.c

### Getting Pre-Built Packages

Pre-Built JAR files (called `openfasttrace-4.0.0.jar`) are available from the following places:
Pre-Built JAR files (called `openfasttrace-4.0.1.jar`) are available from the following places:

* [Maven Central](https://repo1.maven.org/maven2/org/itsallcode/openfasttrace/openfasttrace/4.0.0/openfasttrace-4.0.0.jar)
* [GitHub](https://github.com/itsallcode/openfasttrace/releases/download/4.0.0/openfasttrace-4.0.0.jar)
* [Maven Central](https://repo1.maven.org/maven2/org/itsallcode/openfasttrace/openfasttrace/4.0.1/openfasttrace-4.0.1.jar)
* [GitHub](https://github.com/itsallcode/openfasttrace/releases/download/4.0.1/openfasttrace-4.0.1.jar)

Check our [developer guide](doc/developer_guide.md#getting-the-openfasttrace-library) to learn how to use the OFT JAR as dependency in your own code with popular build tools.

Expand All @@ -97,7 +97,7 @@ If you just want to run OFT:
The most basic variant to run OpenFastTrace is directly from the JAR file via the command line:

```bash
java -jar product/target/openfasttrace-4.0.0.jar trace /path/to/directory/being/traced
java -jar product/target/openfasttrace-4.0.1.jar trace /path/to/directory/being/traced
```

If you want to run OFT automatically as part of a continuous build, we recommend using our plugins for [Gradle](https://github.com/itsallcode/openfasttrace-gradle) and [Maven](https://github.com/itsallcode/openfasttrace-maven-plugin).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class SpecificationItemId implements Comparable<SpecificationItemId>
/** Regexp pattern for revision number. */
public static final String ITEM_REVISION_PATTERN = "(\\d+)";
/** Regexp pattern for item names. */
public static final String ITEM_NAME_PATTERN = "(?U)(\\p{Alpha}[\\w-]*(?:\\.\\p{Alpha}[\\w-]*)*+)";
public static final String ITEM_NAME_PATTERN = "(?U)(\\p{Alpha}[\\w-]*(?:\\.[\\w-]+)*+)";
private static final String LEGACY_ID_NAME = "(\\p{Alpha}+)(?:~\\p{Alpha}+)?:"
+ ITEM_NAME_PATTERN;
/** Separator between artifact type and name in an item ID. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,16 @@ class TestSpecificationItemId
"type~name-trailing-~42, type, name-trailing-, 42",
"foobar~utf-8.compatible.äöü~333, foobar, utf-8.compatible.äöü, 333",
// Deprecated Elektrobit-style specification item ID
"'feat:foo, v1', feat, foo, 1"
"'feat:foo, v1', feat, foo, 1",
"req~ab1~2, req, ab1, 2", // Name ends with a number
"req~ab.1~2, req, ab.1, 2", // Numbers directly after dot
"req~ab__1~2, req, ab__1, 2", // Consecutive underscores
"req~ab--1~2, req, ab--1, 2", // Consecutive dashes
// ID with multiple dots
"req~SR.AB.a.b.c~2, req, SR.AB.a.b.c, 2",
"req~SR.AB.1.1.1~2, req, SR.AB.1.1.1, 2",
"req~SR.AB.1_1_1~2, req, SR.AB.1_1_1, 2",
"req~SR.AB.a_b_c~2, req, SR.AB.a_b_c, 2",
})
void parsingValidIdsSucceeds(final String id, final String expectedType, final String expectedName,
final int expectedRevision)
Expand Down Expand Up @@ -62,14 +71,19 @@ void testParseId_IllegalNumberFormat()

@CsvSource({
"feat.foo~1",
"foo~1",
"req~foo",
"req1~foo~1",
"req.r~foo~1",
"req~1foo~1",
"req~.foo~1",
"req~foo.~1",
"req~foo~-1",
"foo~1", // missing name
"req~foo", // missing revision
"req1~foo~1", // type ends with number
"1req~abc~2", // type with leading number
"re1q~abc~2", // type contains number
"req.r~foo~1", // type contain a dot
"req~1foo~1", // name starts with number
"req~.foo~1", // name begins with a dot
"req~foo.~1", // name ends with a dot
"req~_foo~1", // name starts with underscore
"req~-foo~1", // name starts with dash
"req~foo~-1", // negative revision
"req~foo..a~0", // consecutive dots
})
@ParameterizedTest(name = "Parsing of id ''{0}'' fails")
void testParseId_mustFailForIllegalIds(final String illegalId)
Expand Down
1 change: 1 addition & 0 deletions doc/changes/changes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Changes

* [4.0.1](changes_4.0.1.md)
* [4.0.0](changes_4.0.0.md)
* [3.8.0](changes_3.8.0.md)
* [3.7.1](changes_3.7.1.md)
Expand Down
11 changes: 11 additions & 0 deletions doc/changes/changes_4.0.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# OpenFastTrace 4.0.1, released 2024-06-22

Code name: Allow numbers after dots in specification item names

## Summary

This release allows using specification item names with dots `.` followed by numbers, e.g. `req~SR.AB.1.1.1~1`. We also updated the relevant [section in the user guide](../user_guide.md#specification-item-name). Thanks to [@RobertZickler](https://github.com/RobertZickler) for reporting this!

## Bugfixes

* #417: Allow numbers after dots in specification item names (reported by [@RobertZickler](https://github.com/RobertZickler))
42 changes: 28 additions & 14 deletions doc/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ We use this term to better distinguish between the accepted use of the word "req
The identifier (ID) of a [specification item](#specification-item) is a project-globally unique key which is used to refer to a specification item.

The specification item ID consists of the following parts:
* [Artifact type](#artifact-type)
* Name
* [Artifact type](#specification-item-artifact-type)
* [Name](#specification-item-name)
* [Revision](#specification-item-revision)

All parts are integral to the ID. The name alone is neither unique nor complete. In OFT's native document formats the ID is represented as a character string where the three parts are separated by the tilde ("~") symbol.
All parts are integral to the ID. The name alone is neither unique nor complete. In OFT's native document formats the ID is represented as a character string where the three parts are separated by the tilde (`~`) symbol.

Examples:

Expand All @@ -92,18 +92,16 @@ Examples:
dsn~html5-exporter~1
utest~html5-exporter~4

The name part of the ID must be a character string consisting of Unicode letters and or numbers separated by underscore ("_"), hyphen ("-") or dot ("."). Whitespaces are not allowed.
The following sections explain the each of the three parts in detail.

The revision number is a positive integer number that can be started at zero but out of convention usually is started at one.

#### Artifact Type
##### Specification Item Artifact Type

The artifact type serves two purposes:

1. identifying the source document type
2. identifying the position in the tracing hierarchy

Artifact types are represented by character strings consisting out of ASCII letters and numbers. No other characters are allowed.
Artifact types are represented by character strings consisting out of ASCII letters. No other characters are allowed.

While not enforced by OFT the following strings are well established:

Expand All @@ -116,14 +114,30 @@ While not enforced by OFT the following strings are well established:
* `itest` - integration test
* `stest` - system test
* `uman` - user manual
* `oman` - operation manual

If you don't distinguish between architectural and detailed design we recommend using `dsn` for both. The OFT specification for example does it that way.

How many types you introduce, how you name and stack them is up to you. When we designed OFT, we were clear about the fact that we would not be able to cover all possible artifact types one could imagine, so we did not hardcode them into OFT.

#### Specification Item Revision
##### Specification Item Name

The name part of the ID must be a character string consisting of Unicode letters and/or numbers separated by underscore (`_`), hyphen (`-`) or dot (`.`). Whitespaces are not allowed.

* Names must start with a unicode letter
* Consecutive dots `.` are not allowed

We recommend using a dot `.` to create a hierarchy of items:

exporter.html5.folding
exporter.html5.colors
exporter.csv.column_names

##### Specification Item Revision

The revision number of a specification item is a positive integer number that can be started at zero but by convention usually is started at one.

The revision of a specification item is intended to obsolete existing coverage links in case the content of a specification item semantically changed. Incrementing the revision voids all existing links to this item so that authors linking to the item know they have to check for changes and adapt the covering items.
The revision is intended to obsolete existing coverage links in case the content of a specification item semantically changed. Incrementing the revision voids all existing links to this item so that authors linking to the item know they have to check for changes and adapt the covering items.

Examples:

Expand All @@ -141,17 +155,17 @@ Normative passages contain requirements (or in OFT terms ["specification items"]

#### Coverage

The term "coverage" describes the relation between [specification items](#specification-item) that require detailing, implementation or verification and the items providing just that. This is done by listing all [artifact types](#artifact-type) where the author of a specification item expects to see coverage for that item.
The term "coverage" describes the relation between [specification items](#specification-item) that require detailing, implementation or verification and the items providing just that. This is done by listing all [artifact types](#specification-item-artifact-type) where the author of a specification item expects to see coverage for that item.

A specification item is covered when for each of the required artifact types at least one item exists that covers the original item.

#### Deep Coverage

Deep coverage is a special form of coverage. Achieving deep coverage means that not only is a [specification item](#specification-item) covered by all required [artifact types](#artifact-type), but also the covering items are all covered.
Deep coverage is a special form of coverage. Achieving deep coverage means that not only is a [specification item](#specification-item) covered by all required [artifact types](#specification-item-artifact-type), but also the covering items are all covered.

#### Terminating Specification Item

A [specification item](#specification-item) terminates a chain of items if it does not require coverage in any [artifact type](#artifact-type).
A [specification item](#specification-item) terminates a chain of items if it does not require coverage in any [artifact type](#specification-item-artifact-type).

Example:

Expand Down Expand Up @@ -197,7 +211,7 @@ The upside of giving requirements a title is that they appear in Markdown outlin

The number of hash marks in front of the title must adhere to the rules of Markdown, meaning that if you want to put a [specification item](#specification-item) inside a section with a level two header, the item title must start with three hash marks.

At the moment the specification item above is a [terminating item](#terminating-specification-item) because it does not require coverage by any [artifact type](#artifact-type). Since a user level requirement always needs coverage in other artifact types, we are going to add this next.
At the moment the specification item above is a [terminating item](#terminating-specification-item) because it does not require coverage by any [artifact type](#specification-item-artifact-type). Since a user level requirement always needs coverage in other artifact types, we are going to add this next.

### The Requirement Title
`req~this-is-the-id~1`
Expand Down
2 changes: 1 addition & 1 deletion parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<description>Free requirement tracking suite</description>
<url>https://github.com/itsallcode/openfasttrace</url>
<properties>
<revision>4.0.0</revision>
<revision>4.0.1</revision>
<java.version>17</java.version>
<junit.version>5.11.0-M2</junit.version>
<maven.surefire.version>3.2.5</maven.surefire.version>
Expand Down
2 changes: 2 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
<properties>
<sonar.organization>itsallcode</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
<!-- Exclude abstract base test from coverage -->
<sonar.coverage.exclusions>testutil/src/main/java/org/itsallcode/openfasttrace/testutil/importer/lightweightmarkup/AbstractLightWeightMarkupImporterTest.java</sonar.coverage.exclusions>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- This root module does not produce any artifacts.
We use the minimal timestamp to suppress a warning by artifact:compare. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,21 @@ void testSpecificationItemReferenceDetected()
.build()));
}

@Test
void testSpecificationItemReferenceWithDots()
{
assertImport(PATH, """
`req~SR.AB.1.1.1~2`
Covers:
* `feat~SR.CD.1.2.3~4`
""",
contains(item()
.id("req", "SR.AB.1.1.1", 2)
.addCoveredId("feat", "SR.CD.1.2.3", 4)
.location(PATH.toString(), 1)
.build()));
}

// [utest -> dsn~md.covers-list~1]
@Test
void testSpecificationItemCoversList()
Expand Down

0 comments on commit 63c846a

Please sign in to comment.