If you had a sentence grammar (explained below) with the template "Enter the user name ", the value username is a Cell used to collect information from a user. The template above would result in this bit of html in the specification editor:
Cells can be either inputs (the "Arrange" or "Act" portion of a specification) or assertion values that will be verified as an expectation against an actual value (the "Assert" part of a specification). As discussed in the following sections, Cells can be customized to provide better usability in the user inferface tooling or html rendering.
Asserting Values
Smoke tests that simply prove that an operation does not blow up with exceptions can be useful, but sooner or later you will probably want to assert that some value or state in the system under test matches your expectation. In Storyteller, some Cells can act as assertions to compare the expected value input by the specification author against the actual value. Revisiting the Calculator problem domain from the tutorial, the html results for successful, failed, and invalid cell assertions are shown in the sample specification below:
In the case of invalid data, you can click on the yellow cell to see a popup modal with the full error message for the conversion failure.
See Asserting Values for more information.
Customizing Cells
The original goal of Storyteller was to correct what we felt were usability flaws with FitNesse for specification authoring. Our hope was that we could make the Storyteller user interface do much more to guide the usage of the grammar language with fewer user input errors -- but do that without losing any flexibility in the expression of the grammar language.
You can customize Cell appearance and editing in a couple different ways:
- Header -- change the heading for Cell's within tabular grammars
- Editor -- change the editor control that Storyteller uses for the cell in the specification editor. This isn't terribly useful now as the only choices are the default textbox, select lists, and a checkbox for boolean values, but the plan is for more options in the future.
- Selection lists and values -- To guide the usage in the editor, you can force the user to provide Cell inputs from a selection list. See Selection Lists for much more information.
- Default Values -- You can supply a default value for a Cell as a string. The immediate benefit is to make specification editing quicker if you can live with the default values. Also see Tables for more information about using optional columns in table grammars.
Customizing via Attributes
For grammars that call a fixture method directly, you can use .Net attributes on the method parameters (including the return value using the return:
prefix) like this example of a table grammar:
[ExposeAsTable("Table with lots of options")]
public void TableWithLotsOfOptions(
[Header("Player Name")]string player,
[Header("Position"), DefaultValue("Outfield")]
[SelectionValues("Pitcher", "Outfield", "Catcher")]
string position
)
{
// Set up your roster
}
In the html rendering, a specification using that grammar looks like this:
The available attributes are:
[DefaultValue(value)]
to specify the default value for a cell[Header(the heading)]
to specify the header value displayed in tables[return: AliasAs(cell alias)]
to override the cell name for the return value of a method[Editor(editor type)]
to override the editor selection for a cell[SelectionList(list name)]
to specify a named list of selection values[SelectionValues(values)]
to directly specify a list of selection values for this list
Customizing Cells Programmatically
For users familiar with Storyteller 1.0-2.0, the syntax shown below is brand new to 3.0 to address the complaints about inconsistency and missing options in the various kinds of grammars.
For the grammars (set verifications, some kinds of tables, paragraphs) that are defined through some kind of fluent interface, Storyteller 3.0 introduces the ICellExpression
syntax to customize cell properties:
public interface ICellExpression
{
ICellExpression Header(string header);
ICellExpression Editor(string editor);
ICellExpression DefaultValue(string @default);
ICellExpression SelectionValues(params string[] values);
ICellExpression SelectionOptions(params Option[] options);
ICellExpression SelectionList(string listName);
}
In usage, the cell expression is used as part of a fluent interface like this example from a set verification grammar:
public IGrammar OrderedDetailsAre()
{
return VerifySetOf(getDetails)
.Titled("The Ordered details should be")
.Ordered()
// Use this syntax if you want to customize
// the cells in this SetVerification grammar
.Comparisons(_ =>
{
_.Compare(o => o.Amount).DefaultValue("100").Header("The Amount");
_.Compare(o => o.Date)
// Adding a selection list by display/value
.SelectionOptions(
new Option("Today", "TODAY"),
new Option("Yesterday", "TODAY-1"),
new Option("Tomorrow", "TODAY+1")
);
_.Compare(o => o.Name)
.Header("The Name")
// Simple value list
.SelectionValues("Hank", "Tom", "Alice");
// Simply refer to a selection list
// defined elsewhere by name
_.Compare(o => o.Part)
.SelectionList("Parts");
});
}
Because the usage was so common on a big project, there are now DefaultIsEmpty()
and DefaultIsNull()
extension methods for setting default cell values.
Default Editor Rules
There are only a couple built in rules (for now) for how Storyteller selects an editor for a cell:
- If a cell type is an enumeration type, use a select editor with all the possible values for that enumeration. (This was a very common request for 3.0).
- If a cell type is a boolean, use a checkbox as the editor
- If a cell has either a named selection list or selection values, use a select box
- Otherwise, use a textbox that grows or shrinks to the size of the cell value (a big improvement for 3.0 in the opinion of this author).
Big Text Editor
If you need to use a string cell in your specifications that would be more easily edited and displayed with a larger, multi-line textbox, you can use the bigtext editor like this:
[Header("The City")]
[Default("Cedar Park")]
[Editor("bigtext")]
public string City { get; set; }
Display Only Cells
This is admittedly an oddball feature, but you can also mark cells as display-only such that they are not editable in the specification editor:
[Editor("display-only")]
public int Number { get; set; }
We added this feature at the request of one of our project teams that generated Storyteller specification files programmatically. I'm not entirely sure how useful this editor feature will be outside of that one project.