Skip to content

Allow 'then error' without a reason for a rejection the specification does not name #46

Description

@woksin

then error requires a string, so a specification cannot state that something fails without also naming a reason.

Grammar (Documentation/screenplay/grammar.md:299):

| "then", "error", StringLiteral, NL ;

and the parser (Parsing/SpecificationParser.cs:226) requires the quotes:

[GeneratedRegex("^then\\s+error\\s+\"(" + StringLiteral.BodyPattern + ")\"$",)]

Why this matters

A great many real specifications assert only that an operation was rejected, without naming why — the reason lives in the specification's name, not in the assertion:

public class and_magic_link_is_not_active : given.a_token_exchange
{
    void Because() => Scenario.Execute(new ExchangeToken());

    [Fact] void should_not_be_successful() => Scenario.Result.IsSuccess.ShouldBeFalse();
}

There is nothing in that source naming a reason. Measured while generating from a real production application: 347 of 507 recovered specifications are this shape — roughly two thirds.

Today the only expressible form is an empty string:

specification WhenExchangingAndMagicLinkIsNotActive
  when ExchangeToken
  then error ""

That parses, and it is not wrong — but "" reads as a reason that was left blank rather than one that was never stated, and at that volume it is a lot of empty quotes in a document meant to be read.

Suggested direction

Allow then error on its own, meaning "this is rejected, for a reason the specification does not name":

specification WhenExchangingAndMagicLinkIsNotActive
  when ExchangeToken
  then error

Keep then error "…" exactly as it is for the case where a reason is named — a constraint violation, a validation message. The distinction between the two is real and worth carrying: one says "rejected for this reason", the other says "rejected, reason unspecified here".

Points worth deciding:

  • Whether a bare then error and a then error "…" may appear in the same specification.
  • Whether the printer should round-trip a bare then error unchanged (it must, for generated documents to be diffable).

Context

Filed while implementing specification recovery in Cratis.Arc.Screenplay (Cratis/Arc#2404, PR Cratis/Arc#2413). The generator currently emits then error "" because it is the only available form, and refuses to invent a reason — writing "rejected" or "validation failed" would put a sentence in the document that the application never states.

Related: #27 (reserved directive keywords colliding with property names), also found generating from a real application.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions