Skip to content
Branch: master
Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
..
Failed to load latest commit information.
src
README.md
build.gradle

README.md

requirements as code extract

With requirements as code extract, you can generate plain text documentation (e.g HTML pages) from a model inside the code. The model is defined with the requirements as code core project.

Getting started

If you are using Maven, include the following in your POM:

  <dependency>
    <groupId>org.requirementsascode</groupId>
    <artifactId>requirementsascodeextract</artifactId>
    <version>1.2.1</version>
  </dependency>

If you are using Gradle, include the following in your build.gradle:

compile 'org.requirementsascode:requirementsascodeextract:1.2.1'

This will put the following libraries on the classpath:

  • freemarker-2.3.28.jar (FreeMarker)
  • commons-lang3-3.5.jar (Apache Commons)
  • The current requirements as code extract jar
  • The current requirements as code core jar

Using requirements as code extract

Build a model

First, you need to build a model using the requirements as code core project:

Model model = Model.builder()
  .useCase("Use credit card")
    .basicFlow()
    	.step(ASSIGN).user(requestsToAssignLimit).system(assignsLimit)
	.step(WITHDRAW).user(requestsWithdrawal).system(withdraws).reactWhile(accountOpen)
	.step(REPAY).user(requestsRepay).system(repays).reactWhile(accountOpen)
    
    .flow("Withdraw again").after(REPAY)
	.step(WITHDRAW_AGAIN).user(requestsWithdrawal).system(withdraws)
	.step(REPEAT).continuesAt(WITHDRAW)
	    	
    .flow("Cycle is over").anytime()
	.step(CLOSE).on(requestToCloseCycle).system(closesCycle)
	    	
    .flow("Assign limit twice").condition(limitAlreadyAssigned)
	.step(ASSIGN_TWICE).user(requestsToAssignLimit).system(throwsAssignLimitException)
	    	
    .flow("Too many withdrawals").condition(tooManyWithdrawalsInCycle) 
         .step(WITHDRAW_TOO_OFTEN).user(requestsWithdrawal).system(throwsTooManyWithdrawalsException)
 .build();

You have to use classes with special names in the model, as the engine will create documentation from these names.

For example, in step REPAY, the requestsRepay constant references the following class:

public class RequestsRepay {
    private BigDecimal amount;
    public RequestsRepay(BigDecimal amount) {
        this.amount = amount;
    }
    public BigDecimal getAmount() {
        return amount;
    }
}

The name of the class needs to be of the form VerbNoun, in third person singular. In the example, it is RequestsRepay. The documentation created from step REPAY is: "Repay: As long as account open: User requests repay. System repays."

Use template engine to generate documentation

You can create the engine like this:

FreeMarkerEngine engine = new FreeMarkerEngine(basePackagePath);

For basePackagePath, you specify your own package path in your classpath, where your FreeMarker templates are located. For example, if you use standard src/main/resources or src/test/resources folders, this is the package path below that folder.

You can generate the documentation with this call:

engine.extract(model, templateFileName, outputWriter);

The first parameter is the model, as shown above. The second parameter is the name of the template file, relative to the base package path (during construction). The third parameter is a java.io.Writer that produces the output text.

Here's an example FreeMarker template file:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <title>Requirements as Code - Extract Example</title>
</head>
<body>
  	<#list model.useCases as useCase>
  		<h1>Use Case: ${useCase?capitalize}</h1>
		<#list useCase.flows as f>
	  		<h2>${f}</h2>
	  		<div>${flowCondition(f)}</div>
			<#list f.steps as s>
				<div>${s}. ${reactWhileOfStep(s)}${actorPartOfStep(s)}${userPartOfStep(s)}${systemPartOfStep(s)}</div>
			</#list>
		</#list>
  	</#list>
</body>
</html>

The template file starts with the model instance provided by the engine, then it iterates over the model.

See the FreeMarker documentation for details. See this test class for details on how to use requirements as code extract.

Example document

Here's the full document generated from the above model:

Use Credit Card

Basic flow

Assign limit: User requests to assign limit. System assigns limit.
Withdraw: As long as account open: User requests withdrawal. System withdraws.
Repay: As long as account open: User requests repay. System repays.

Withdraw again

After Repay:
Withdraw again: User requests withdrawal. System withdraws.
Repeat: System continues at Withdraw.

Cycle is over

Anytime:
Close cycle: Handles RequestToCloseCycle: System closes cycle.

Assign limit twice

Anytime, when limit already assigned:
Assign limit twice: User requests to assign limit. System throws assign limit exception.

Too many withdrawals

Anytime, when too many withdrawals in cycle:
Withdraw too often: System throws too many withdrawals exception.
You can’t perform that action at this time.