Design by Contract Library for Groovy
This project aims to provide contract annotations that support the specification of class-invariants, pre- and post-conditions on Groovy classes and interfaces.
In addition, GContracts supports postconditions with the old and result variable and inheritance of all assertion types.
import org.gcontracts.annotations.*
@Invariant({ speed() >= 0 })
class Rocket {
@Requires({ isStarted() })
@Ensures({ old.speed < speed })
def accelerate() { ... }
boolean isStarted() { ... }
def speed() { ... }
}
GContracts comes as single JAR file, without any third-party dependencies.
@Invariant, @Requires and @Ensures
Groovydoc Ant task to generate Javadocs with contract information-ea and -da VM parametersIf you want to know about more about some of these features, checkout the Wiki pages.
The Stack example is a classic way demonstrating the power of contracts in class libraries. Here is a Groovy example leveraging the GContracts library:
@Grab(group='org.gcontracts', module='gcontracts-core', version='[1.2.12,)')
import org.gcontracts.annotations.*
@Invariant({ elements != null })
class Stack<T> {
List<T> elements
@Ensures({ is_empty() })
def Stack() {
elements = []
}
@Requires({ preElements?.size() > 0 })
@Ensures({ !is_empty() })
def Stack(List<T> preElements) {
elements = preElements
}
boolean is_empty() {
return elements.isEmpty()
}
@Requires({ !is_empty() })
T last_item() {
return elements.get(count() - 1)
}
def count() {
return elements.size()
}
@Ensures({ result == true ? count() > 0 : count() >= 0 })
boolean has(T item) {
return elements.contains(item)
}
@Ensures({ last_item() == item })
def push(T item) {
return elements.add(item)
}
@Requires({ !is_empty() })
@Ensures({ last_item() == item })
def replace(T item) {
remove()
return elements.add(item)
}
@Requires({ !is_empty() })
@Ensures({ result != null })
T remove() {
return elements.remove(count() - 1)
}
String toString() { elements.toString() }
}
def stack = new Stack<Integer>()
You can copy and paste the above example to your groovyConsole and hit the run button.
GContracts is available at the central Maven repository and as binary download at Github. Add gcontracts-core-xxx.jar to your project's classpath and you're ready to go.
As of 1.2.11, GContracts comes with embedded support for the Groovy/Grails tool suite >= 3.2.0 (Eclipse) and IntelliJ >= 12.1.
The library runs with Groovy >= 1.8 and can be used in statically (with @CompileStatic) and dynamically typed code.