Example Object

Context

You want to explore questions about domain objects that are in particular execution states.

Problem:

How do you create an object in a particular state to start a moldable development task?

Forces

Concrete examples are need for many purposes, such as documentation, testing, and exploration.

Examples can be complex to set up. Unit tests consume examples, but they are only accessible if a test fails.

Solution:

Wrap examples as (instance) methods that optionally evaluate some tests (assertions), and return the example instance. Each example may also use one or more examples as the initial setup for the new example.

Steps

To start, you need a modified unit testing framework in which tests return the exercised fixture, namely, an example. In GT, you create an Example by defining a parameterless method that has a <gtExample> pragma, and returns an object. (A similar framework for Java is JExample.)

Here's a simple example that returns a parse node for the parsed string '3+4', and asserts that the result is not fully reduced (evaluated).

a3plus4
	<gtExample>
	| result |
	result := self parseExpression: '3+4'.
	self assert: result isReduced not.
	^ result
    

Unlike normal test methods, examples can be composed. For example, this example method performs an evaluation step on the previous example, and returns the fully reduced expression node, asserting that no more evaluation steps can be performed.

a3plus4is7
	<gtExample>
	| result context |
	context := self a3plus4 asContext.
	result := context step.
	self assert: result isSPLValue.
	self assert: result value equals: 7.
	^ result
    

Consequences

Examples can be run just like classical unit tests.

When an example fails, its dependent examples do not need to be run.

When an example succeeds, it can be inspected, used as a moldable object to start coding, or embedded as a live example snippet within a notebook page to illustrate some point. (The example snippets above illustrate this.)

When you are searching for usages of an API, not only do you find examples that illustrate the usage, but by running the example you obtain a live instance that you can explore.

Related patterns

Examples can be embedded in the notebook pages of a Project Diary.

Examples can produce a Moldable Object for moldable development.