Sign in

    cucumber-messages

    Cucumber Messages protocol types for MoonBit with JSON serialization and NDJSON streaming

    cucumber
    messages
    bdd
    testing
    protocol
    Download zip
    Author
    Version
    0.3.0
    License
    Apache-2.0
    Last updated
    26 days ago
    Downloads
    9K

    #moonrockz/cucumber-messages

    Cucumber Messages protocol types for MoonBit. Defines the standardized message types used by Cucumber for representing test execution results.

    #Installation

    moon add moonrockz/cucumber-messages

    #What are Cucumber Messages?

    Cucumber Messages is a message protocol for representing the results of running Cucumber tests. Messages are exchanged as NDJSON (newline-delimited JSON) streams -- one JSON object per line, each wrapped in an Envelope.

    This decouples Gherkin parsing from test execution, enables real-time result processing, and reduces memory consumption compared to traditional JSON/XML formats.

    #Message Types

    The protocol defines message types wrapped in an Envelope discriminated union:

    CategoryMessage Types
    Source & ParsingSource, GherkinDocument, ParseError
    Test CompilationPickle
    Glue DefinitionsStepDefinition, Hook, ParameterType
    Test Run LifecycleTestRunStarted, TestRunFinished
    Test Case LifecycleTestCase, TestCaseStarted, TestCaseFinished
    Step LifecycleTestStepStarted, TestStepFinished
    Hook LifecycleTestRunHookStarted, TestRunHookFinished
    ArtifactsAttachment, ExternalAttachment
    MetadataMeta, Suggestion, UndefinedParameterType

    #Usage

    // Deserialize a message from JSON (use your package alias for Envelope, e.g. @cm)
    let json = @json.parse(
    "{\"meta\": {\"protocolVersion\": \"27.0.0\", \"implementation\": {\"name\": \"cucumber-moonbit\"}, \"runtime\": {\"name\": \"moonbit\"}, \"os\": {\"name\": \"linux\"}, \"cpu\": {\"name\": \"amd64\"}}}"
    ) catch { _ => panic() }
    let envelope : Envelope = @json.from_json(json) catch { _ => panic() }

    // Serialize a message to JSON
    let json_value = envelope.to_json()

    // NDJSON streaming: parse multiple messages from newline-delimited JSON
    let envelopes = @cm.parse_ndjson(ndjson_string) catch { _ => panic() }

    // Serialize envelopes to NDJSON
    let ndjson = @cm.envelopes_to_ndjson(envelopes)

    #Compatibility

    This library targets Cucumber Messages protocol v27.0.0. It is designed to interoperate with other Cucumber implementations (Java, JavaScript, Ruby, Python, Go, etc.) via the shared NDJSON format.

    #License

    Apache-2.0

    Attachment

    pub struct Attachment {
    body : String
    contentEncoding : AttachmentContentEncoding
    mediaType : String
    fileName : String?
    source : Source?
    testCaseStartedId : String?
    testStepId : String?
    url : String?
    testRunStartedId : String?
    testRunHookStartedId : String?
    timestamp : Timestamp?
    } derive(ToJson,
    FromJson
    )

    Attachment: embedded test artifact.

    Attachment::to_json

    fn Attachment::to_json(Attachment) -> Json

    AttachmentContentEncoding

    pub enum AttachmentContentEncoding {
    Identity
    Base64
    }

    AttachmentContentEncoding: encoding of attachment body.

    AttachmentContentEncoding::to_json

    Background

    pub struct Background {
    location : Location
    keyword : String
    name : String
    description : String
    steps : Array[Step]
    id : String
    } derive(ToJson,
    FromJson
    )

    Background: a background in a feature or rule.

    Background::to_json

    fn Background::to_json(Background) -> Json

    pub struct Ci {
    name : String
    url : String?
    buildNumber : String?
    git : Git?
    } derive(ToJson,
    FromJson
    )

    Ci: CI environment (Meta sub-type).

    Ci::to_json

    fn Ci::to_json(Ci) -> Json

    Comment

    pub struct Comment {
    location : Location
    text : String
    } derive(ToJson,
    FromJson
    )

    Comment: a comment in a Gherkin document.

    Comment::to_json

    fn Comment::to_json(Comment) -> Json

    DataTable

    pub struct DataTable {
    location : Location
    rows : Array[TableRow]
    } derive(ToJson,
    FromJson
    )

    DataTable: a data table in a step.

    DataTable::to_json

    fn DataTable::to_json(DataTable) -> Json

    DocString

    pub struct DocString {
    location : Location
    content : String
    delimiter : String
    mediaType : String?
    } derive(ToJson,
    FromJson
    )

    DocString: a doc string in a step.

    DocString::to_json

    fn DocString::to_json(DocString) -> Json

    Duration

    pub struct Duration {
    seconds : Int
    nanos : Int
    } derive(ToJson,
    FromJson
    )

    Duration: seconds + nanos (0..999_999_999).

    Duration::to_json

    fn Duration::to_json(Duration) -> Json

    Envelope

    pub enum Envelope {
    Meta(Meta)
    Source(Source)
    ParseError(ParseError)
    TestRunStarted(TestRunStarted)
    TestRunFinished(TestRunFinished)
    UndefinedParameterType(UndefinedParameterType)
    TestCaseStarted(TestCaseStarted)
    TestCaseFinished(TestCaseFinished)
    TestStepStarted(TestStepStarted)
    TestStepFinished(TestStepFinished)
    Attachment(Attachment)
    ExternalAttachment(ExternalAttachment)
    Hook(Hook)
    StepDefinition(StepDefinition)
    ParameterType(ParameterType)
    Suggestion(Suggestion)
    TestRunHookStarted(TestRunHookStarted)
    TestRunHookFinished(TestRunHookFinished)
    GherkinDocument(GherkinDocument)
    Pickle(Pickle)
    TestCase(TestCase)
    }

    Envelope: exactly one message variant per JSON object.
    impl ToJson for Envelope

    Envelope::to_json

    fn Envelope::to_json(self : Envelope) -> Json

    Envelope::to_ndjson_line

    fn Envelope::to_ndjson_line(self : Envelope) -> String

    Serialize an Envelope to a single NDJSON line (no trailing newline).

    Examples

    pub struct Examples {
    location : Location
    tags : Array[Tag]
    keyword : String
    name : String
    description : String
    tableHeader : TableRow?
    tableBody : Array[TableRow]
    id : String
    } derive(ToJson,
    FromJson
    )

    Examples: examples table for a scenario outline.

    Examples::to_json

    fn Examples::to_json(Examples) -> Json

    Exception

    pub struct Exception {
    type_ : String
    message : String?
    stackTrace : String?
    }

    Exception: simplified exception (type, optional message and stackTrace).
    impl ToJson for Exception

    Exception::to_json

    fn Exception::to_json(self : Exception) -> Json

    ExternalAttachment

    pub struct ExternalAttachment {
    url : String
    mediaType : String
    testCaseStartedId : String?
    testStepId : String?
    testRunHookStartedId : String?
    timestamp : Timestamp?
    } derive(ToJson,
    FromJson
    )

    ExternalAttachment: linked test artifact.

    ExternalAttachment::to_json

    Feature

    pub struct Feature {
    location : Location
    tags : Array[Tag]
    language : String
    keyword : String
    name : String
    description : String
    children : Array[FeatureChild]
    } derive(ToJson,
    FromJson
    )

    Feature: a feature in a Gherkin document.

    Feature::to_json

    fn Feature::to_json(Feature) -> Json

    FeatureChild

    pub struct FeatureChild {
    rule : Rule?
    background : Background?
    scenario : Scenario?
    } derive(ToJson,
    FromJson
    )

    FeatureChild: a child of a Feature (rule, background, or scenario).

    FeatureChild::to_json

    GherkinDocument

    pub struct GherkinDocument {
    uri : String?
    feature : Feature?
    comments : Array[Comment]
    } derive(ToJson,
    FromJson
    )

    GherkinDocument: parsed Gherkin AST.

    GherkinDocument::to_json

    Git

    pub struct Git {
    remote : String
    revision : String
    branch : String?
    tag : String?
    } derive(ToJson,
    FromJson
    )

    Git: remote, revision, optional branch and tag (Meta sub-type).

    Git::to_json

    fn Git::to_json(Git) -> Json

    Group

    pub struct Group {
    children : Array[Group]?
    start : Int?
    value : String?
    } derive(ToJson,
    FromJson
    )

    Group: capture group from step matching.

    Group::to_json

    fn Group::to_json(Group) -> Json

    Hook

    pub struct Hook {
    id : String
    sourceReference : SourceReference
    name : String?
    tagExpression : String?
    type_ : HookType?
    }

    Hook: before/after hook definition. Note: JSON key is "type" (not "hookType") to match upstream schema.
    impl ToJson for Hook

    Hook::to_json

    fn Hook::to_json(self : Hook) -> Json

    HookType

    pub enum HookType {
    BeforeTestRun
    AfterTestRun
    BeforeTestCase
    AfterTestCase
    BeforeTestStep
    AfterTestStep
    }

    HookType: lifecycle hook type.
    impl ToJson for HookType

    HookType::to_json

    fn HookType::to_json(self : HookType) -> Json

    JavaMethod

    pub struct JavaMethod {
    className : String
    methodName : String
    methodParameterTypes : Array[String]
    } derive(ToJson,
    FromJson
    )

    JavaMethod: for SourceReference (Java glue).

    JavaMethod::to_json

    fn JavaMethod::to_json(JavaMethod) -> Json

    JavaStackTraceElement

    pub struct JavaStackTraceElement {
    className : String
    fileName : String
    methodName : String
    } derive(ToJson,
    FromJson
    )

    JavaStackTraceElement: for SourceReference.

    JavaStackTraceElement::to_json

    KeywordType

    pub enum KeywordType {
    Unknown
    Context
    Action
    Outcome
    Conjunction
    }

    KeywordType: keyword type for a step.

    KeywordType::to_json

    fn KeywordType::to_json(self : KeywordType) -> Json

    Location

    pub struct Location {
    line : Int
    column : Int?
    } derive(ToJson,
    FromJson
    )

    Location: line and optional column in a text file (Cucumber Messages).

    Location::to_json

    fn Location::to_json(Location) -> Json

    Meta

    pub struct Meta {
    protocolVersion : String
    implementation : Product
    runtime : Product
    os : Product
    cpu : Product
    ci : Ci?
    } derive(ToJson,
    FromJson
    )

    Meta: protocol metadata (protocolVersion, implementation, runtime, os, cpu, optional ci).

    Meta::to_json

    fn Meta::to_json(Meta) -> Json

    ParameterType

    pub struct ParameterType {
    id : String
    name : String
    preferForRegularExpressionMatch : Bool
    regularExpressions : Array[String]
    useForSnippets : Bool
    sourceReference : SourceReference?
    } derive(ToJson,
    FromJson
    )

    ParameterType: custom parameter type for step expressions.

    ParameterType::to_json

    ParseError

    pub struct ParseError {
    source : SourceReference
    message : String
    } derive(ToJson,
    FromJson
    )

    ParseError: parse error with source reference and message.

    ParseError::to_json

    fn ParseError::to_json(ParseError) -> Json

    Pickle

    pub(all) struct Pickle {
    id : String
    uri : String
    name : String
    language : String
    steps : Array[PickleStep]
    tags : Array[PickleTag]
    astNodeIds : Array[String]
    location : Location?
    } derive(ToJson,
    FromJson
    )

    Pickle: compiled test case from a scenario.

    Pickle::to_json

    fn Pickle::to_json(Pickle) -> Json

    PickleDocString

    pub(all) struct PickleDocString {
    content : String
    mediaType : String?
    } derive(ToJson,
    FromJson
    )

    PickleDocString: a doc string in a pickle step.

    PickleDocString::to_json

    PickleStep

    pub(all) struct PickleStep {
    id : String
    text : String
    astNodeIds : Array[String]
    type_ : PickleStepType?
    argument : PickleStepArgument?
    }

    PickleStep: a step in a pickle. Note: JSON key is "type" (not "pickleStepType") to match upstream schema.

    PickleStep::to_json

    fn PickleStep::to_json(self : PickleStep) -> Json

    PickleStepArgument

    pub(all) struct PickleStepArgument {
    docString : PickleDocString?
    dataTable : PickleTable?
    } derive(ToJson,
    FromJson
    )

    PickleStepArgument: argument for a pickle step.

    PickleStepArgument::to_json

    PickleStepType

    pub(all) enum PickleStepType {
    Unknown
    Context
    Action
    Outcome
    }

    PickleStepType: type of a pickle step.

    PickleStepType::to_json

    fn PickleStepType::to_json(self : PickleStepType) -> Json

    PickleTable

    pub(all) struct PickleTable {
    rows : Array[PickleTableRow]
    } derive(ToJson,
    FromJson
    )

    PickleTable: a data table in a pickle step.

    PickleTable::to_json

    fn PickleTable::to_json(PickleTable) -> Json

    PickleTableCell

    pub(all) struct PickleTableCell {
    value : String
    } derive(ToJson,
    FromJson
    )

    PickleTableCell: a cell in a pickle data table.

    PickleTableCell::to_json

    PickleTableRow

    pub(all) struct PickleTableRow {
    cells : Array[PickleTableCell]
    } derive(ToJson,
    FromJson
    )

    PickleTableRow: a row in a pickle data table.

    PickleTableRow::to_json

    PickleTag

    pub(all) struct PickleTag {
    name : String
    astNodeId : String
    } derive(ToJson,
    FromJson
    )

    PickleTag: a tag in a pickle.

    PickleTag::to_json

    fn PickleTag::to_json(PickleTag) -> Json

    Product

    pub struct Product {
    name : String
    version : String?
    } derive(ToJson,
    FromJson
    )

    Product: name and optional version (Meta sub-type).

    Product::to_json

    fn Product::to_json(Product) -> Json

    Rule

    pub struct Rule {
    location : Location
    tags : Array[Tag]
    keyword : String
    name : String
    description : String
    children : Array[RuleChild]
    id : String
    } derive(ToJson,
    FromJson
    )

    Rule: a rule grouping scenarios in a feature.

    Rule::to_json

    fn Rule::to_json(Rule) -> Json

    RuleChild

    pub struct RuleChild {
    background : Background?
    scenario : Scenario?
    } derive(ToJson,
    FromJson
    )

    RuleChild: a child of a Rule (background or scenario).

    RuleChild::to_json

    fn RuleChild::to_json(RuleChild) -> Json

    Scenario

    pub struct Scenario {
    location : Location
    tags : Array[Tag]
    keyword : String
    name : String
    description : String
    steps : Array[Step]
    examples : Array[Examples]
    id : String
    } derive(ToJson,
    FromJson
    )

    Scenario: a scenario in a feature or rule.

    Scenario::to_json

    fn Scenario::to_json(Scenario) -> Json

    Snippet

    pub struct Snippet {
    language : String
    code : String
    } derive(ToJson,
    FromJson
    )

    Snippet: code snippet for a suggestion.

    Snippet::to_json

    fn Snippet::to_json(Snippet) -> Json

    Source

    pub struct Source {
    uri : String
    data : String
    mediaType : SourceMediaType
    } derive(ToJson,
    FromJson
    )

    Source: a source file (uri, data, mediaType).

    Source::to_json

    fn Source::to_json(Source) -> Json

    SourceMediaType

    pub enum SourceMediaType {
    GherkinPlain
    GherkinMarkdown
    }

    Source media type for Source.mediaType.

    SourceMediaType::to_json

    fn SourceMediaType::to_json(self : SourceMediaType) -> Json

    SourceReference

    pub struct SourceReference {
    uri : String?
    javaMethod : JavaMethod?
    javaStackTraceElement : JavaStackTraceElement?
    location : Location?
    } derive(ToJson,
    FromJson
    )

    SourceReference: points to a Source and optional Location (or Java method/stack).

    SourceReference::to_json

    Step

    pub struct Step {
    location : Location
    keyword : String
    text : String
    id : String
    keywordType : KeywordType?
    docString : DocString?
    dataTable : DataTable?
    } derive(ToJson,
    FromJson
    )

    Step: a step in a scenario or background.

    Step::to_json

    fn Step::to_json(Step) -> Json

    StepDefinition

    pub struct StepDefinition {
    id : String
    pattern : StepDefinitionPattern
    sourceReference : SourceReference
    } derive(ToJson,
    FromJson
    )

    StepDefinition: step definition with pattern and source reference.

    StepDefinition::to_json

    StepDefinitionPattern

    pub struct StepDefinitionPattern {
    source : String
    type_ : StepDefinitionPatternType
    }

    StepDefinitionPattern: pattern for a step definition. Note: JSON key is "type" (not "patternType") to match upstream schema.

    StepDefinitionPattern::to_json

    StepDefinitionPatternType

    pub enum StepDefinitionPatternType {
    CucumberExpression
    RegularExpression
    }

    StepDefinitionPatternType: pattern type for step definitions.

    StepDefinitionPatternType::to_json

    StepMatchArgument

    pub struct StepMatchArgument {
    group : Group
    parameterTypeName : String?
    } derive(ToJson,
    FromJson
    )

    StepMatchArgument: argument from step matching.

    StepMatchArgument::to_json

    StepMatchArgumentsList

    pub struct StepMatchArgumentsList {
    stepMatchArguments : Array[StepMatchArgument]
    } derive(ToJson,
    FromJson
    )

    StepMatchArgumentsList: list of step match arguments.

    StepMatchArgumentsList::to_json

    Suggestion

    pub struct Suggestion {
    id : String
    pickleStepId : String
    snippets : Array[Snippet]
    } derive(ToJson,
    FromJson
    )

    Suggestion: snippet suggestion for an undefined step.

    Suggestion::to_json

    fn Suggestion::to_json(Suggestion) -> Json

    TableCell

    pub struct TableCell {
    location : Location
    value : String
    } derive(ToJson,
    FromJson
    )

    TableCell: a cell in a data table row.

    TableCell::to_json

    fn TableCell::to_json(TableCell) -> Json

    TableRow

    pub struct TableRow {
    location : Location
    cells : Array[TableCell]
    id : String
    } derive(ToJson,
    FromJson
    )

    TableRow: a row in a data table.

    TableRow::to_json

    fn TableRow::to_json(TableRow) -> Json

    Tag

    pub struct Tag {
    location : Location
    name : String
    id : String
    } derive(ToJson,
    FromJson
    )

    Tag: a tag in a Gherkin document.

    Tag::to_json

    fn Tag::to_json(Tag) -> Json

    TestCase

    pub struct TestCase {
    id : String
    pickleId : String
    testSteps : Array[TestStep]
    testRunStartedId : String?
    } derive(ToJson,
    FromJson
    )

    TestCase: a test case (compiled from a pickle).

    TestCase::to_json

    fn TestCase::to_json(TestCase) -> Json

    TestCaseFinished

    pub struct TestCaseFinished {
    testCaseStartedId : String
    timestamp : Timestamp
    willBeRetried : Bool
    } derive(ToJson,
    FromJson
    )

    TestCaseFinished: test case attempt finished.

    TestCaseFinished::to_json

    TestCaseStarted

    pub struct TestCaseStarted {
    attempt : Int
    id : String
    testCaseId : String
    workerId : String?
    timestamp : Timestamp
    } derive(ToJson,
    FromJson
    )

    TestCaseStarted: test case attempt started.

    TestCaseStarted::to_json

    TestRunFinished

    pub struct TestRunFinished {
    message : String?
    success : Bool
    timestamp : Timestamp
    exception : Exception?
    testRunStartedId : String?
    } derive(ToJson,
    FromJson
    )

    TestRunFinished: test run finished (success, timestamp, optional message, exception, testRunStartedId).

    TestRunFinished::to_json

    TestRunHookFinished

    pub struct TestRunHookFinished {
    testRunHookStartedId : String
    result : TestStepResult
    timestamp : Timestamp
    } derive(ToJson,
    FromJson
    )

    TestRunHookFinished: hook execution finished.

    TestRunHookFinished::to_json

    TestRunHookStarted

    pub struct TestRunHookStarted {
    id : String
    testRunStartedId : String
    hookId : String
    timestamp : Timestamp
    workerId : String?
    } derive(ToJson,
    FromJson
    )

    TestRunHookStarted: hook execution lifecycle.

    TestRunHookStarted::to_json

    TestRunStarted

    pub struct TestRunStarted {
    timestamp : Timestamp
    id : String?
    } derive(ToJson,
    FromJson
    )

    TestRunStarted: test run lifecycle.

    TestRunStarted::to_json

    TestStep

    pub struct TestStep {
    id : String
    hookId : String?
    pickleStepId : String?
    stepDefinitionIds : Array[String]?
    stepMatchArgumentsLists : Array[StepMatchArgumentsList]?
    } derive(ToJson,
    FromJson
    )

    TestStep: a step in a test case.

    TestStep::to_json

    fn TestStep::to_json(TestStep) -> Json

    TestStepFinished

    pub struct TestStepFinished {
    testCaseStartedId : String
    testStepId : String
    testStepResult : TestStepResult
    timestamp : Timestamp
    } derive(ToJson,
    FromJson
    )

    TestStepFinished: step finished with result.

    TestStepFinished::to_json

    TestStepResult

    pub struct TestStepResult {
    duration : Duration
    status : TestStepResultStatus
    message : String?
    exception : Exception?
    } derive(ToJson,
    FromJson
    )

    TestStepResult: result of a step (duration, status, optional message and exception).

    TestStepResult::to_json

    TestStepResultStatus

    pub enum TestStepResultStatus {
    Unknown
    Passed
    Skipped
    Pending
    Undefined
    Ambiguous
    Failed
    }

    TestStepResultStatus: status of a step.

    TestStepResultStatus::to_json

    TestStepStarted

    pub struct TestStepStarted {
    testCaseStartedId : String
    testStepId : String
    timestamp : Timestamp
    } derive(ToJson,
    FromJson
    )

    TestStepStarted: step lifecycle.

    TestStepStarted::to_json

    Timestamp

    pub struct Timestamp {
    seconds : Int
    nanos : Int
    } derive(ToJson,
    FromJson
    )

    Timestamp: seconds since Unix epoch + nanos (0..999_999_999).

    Timestamp::to_json

    fn Timestamp::to_json(Timestamp) -> Json

    UndefinedParameterType

    pub struct UndefinedParameterType {
    expression : String
    name : String
    } derive(ToJson,
    FromJson
    )

    UndefinedParameterType: reports undefined parameter type.

    UndefinedParameterType::to_json

    envelopes_to_ndjson

    fn envelopes_to_ndjson(envelopes : Array[Envelope]) -> String

    Serialize an array of Envelopes to NDJSON (one JSON object per line).

    parse_ndjson

    fn parse_ndjson(input : String) -> Array[Envelope] raise

    Parse an NDJSON string (multiple lines) into an array of Envelopes. Blank lines are skipped.

    parse_ndjson_line

    fn parse_ndjson_line(line : String) -> Envelope raise

    Parse a single NDJSON line into an Envelope.

    protocol_version

    let protocol_version : String

    Cucumber Messages protocol version.