///|
/// Envelope: exactly one message variant per JSON object.
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)
}
///|
pub impl @json.FromJson for Envelope with from_json(json, path) {
guard json is Object(obj) else {
raise @json.JsonDecodeError((path, "Envelope::from_json: expected object"))
}
if obj.get("meta") is Some(v) {
return Meta(@json.from_json(v, path=path.add_key("meta")))
}
if obj.get("source") is Some(v) {
return Source(@json.from_json(v, path=path.add_key("source")))
}
if obj.get("parseError") is Some(v) {
return ParseError(@json.from_json(v, path=path.add_key("parseError")))
}
if obj.get("testRunStarted") is Some(v) {
return TestRunStarted(
@json.from_json(v, path=path.add_key("testRunStarted")),
)
}
if obj.get("testRunFinished") is Some(v) {
return TestRunFinished(
@json.from_json(v, path=path.add_key("testRunFinished")),
)
}
if obj.get("undefinedParameterType") is Some(v) {
return UndefinedParameterType(
@json.from_json(v, path=path.add_key("undefinedParameterType")),
)
}
if obj.get("testCaseStarted") is Some(v) {
return TestCaseStarted(
@json.from_json(v, path=path.add_key("testCaseStarted")),
)
}
if obj.get("testCaseFinished") is Some(v) {
return TestCaseFinished(
@json.from_json(v, path=path.add_key("testCaseFinished")),
)
}
if obj.get("testStepStarted") is Some(v) {
return TestStepStarted(
@json.from_json(v, path=path.add_key("testStepStarted")),
)
}
if obj.get("testStepFinished") is Some(v) {
return TestStepFinished(
@json.from_json(v, path=path.add_key("testStepFinished")),
)
}
if obj.get("attachment") is Some(v) {
return Attachment(@json.from_json(v, path=path.add_key("attachment")))
}
if obj.get("externalAttachment") is Some(v) {
return ExternalAttachment(
@json.from_json(v, path=path.add_key("externalAttachment")),
)
}
if obj.get("hook") is Some(v) {
return Hook(@json.from_json(v, path=path.add_key("hook")))
}
if obj.get("stepDefinition") is Some(v) {
return StepDefinition(
@json.from_json(v, path=path.add_key("stepDefinition")),
)
}
if obj.get("parameterType") is Some(v) {
return ParameterType(@json.from_json(v, path=path.add_key("parameterType")))
}
if obj.get("suggestion") is Some(v) {
return Suggestion(@json.from_json(v, path=path.add_key("suggestion")))
}
if obj.get("testRunHookStarted") is Some(v) {
return TestRunHookStarted(
@json.from_json(v, path=path.add_key("testRunHookStarted")),
)
}
if obj.get("testRunHookFinished") is Some(v) {
return TestRunHookFinished(
@json.from_json(v, path=path.add_key("testRunHookFinished")),
)
}
if obj.get("gherkinDocument") is Some(v) {
return GherkinDocument(
@json.from_json(v, path=path.add_key("gherkinDocument")),
)
}
if obj.get("pickle") is Some(v) {
return Pickle(@json.from_json(v, path=path.add_key("pickle")))
}
if obj.get("testCase") is Some(v) {
return TestCase(@json.from_json(v, path=path.add_key("testCase")))
}
raise @json.JsonDecodeError(
(path, "Envelope::from_json: no known message key found"),
)
}
///|
pub impl ToJson for Envelope with to_json(self) {
let o : Map[String, Json] = match self {
Meta(m) => { "meta": m.to_json() }
Source(s) => { "source": s.to_json() }
ParseError(p) => { "parseError": p.to_json() }
TestRunStarted(t) => { "testRunStarted": t.to_json() }
TestRunFinished(t) => { "testRunFinished": t.to_json() }
UndefinedParameterType(u) => { "undefinedParameterType": u.to_json() }
TestCaseStarted(t) => { "testCaseStarted": t.to_json() }
TestCaseFinished(t) => { "testCaseFinished": t.to_json() }
TestStepStarted(t) => { "testStepStarted": t.to_json() }
TestStepFinished(t) => { "testStepFinished": t.to_json() }
Attachment(a) => { "attachment": a.to_json() }
ExternalAttachment(e) => { "externalAttachment": e.to_json() }
Hook(h) => { "hook": h.to_json() }
StepDefinition(s) => { "stepDefinition": s.to_json() }
ParameterType(p) => { "parameterType": p.to_json() }
Suggestion(s) => { "suggestion": s.to_json() }
TestRunHookStarted(t) => { "testRunHookStarted": t.to_json() }
TestRunHookFinished(t) => { "testRunHookFinished": t.to_json() }
GherkinDocument(g) => { "gherkinDocument": g.to_json() }
Pickle(p) => { "pickle": p.to_json() }
TestCase(t) => { "testCase": t.to_json() }
}
o.to_json()
}
///|
test "envelope meta decode and roundtrip" {
let raw = "{\"meta\":{\"protocolVersion\":\"27.0.0\",\"implementation\":{\"name\":\"x\"},\"runtime\":{\"name\":\"y\"},\"os\":{\"name\":\"z\"},\"cpu\":{\"name\":\"w\"}}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
Meta(m) => {
assert_eq(m.protocolVersion, "27.0.0")
assert_eq(m.implementation.name, "x")
}
_ => panic()
}
let json2 = env.to_json()
let back : Envelope = @json.from_json(json2) catch { _ => panic() }
match (env, back) {
(Meta(m), Meta(m2)) => assert_eq(m.protocolVersion, m2.protocolVersion)
_ => panic()
}
}
///|
test "envelope source roundtrip" {
let raw = "{\"source\":{\"uri\":\"a.feature\",\"data\":\"Feature: y\",\"mediaType\":\"text/x.cucumber.gherkin+markdown\"}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
Source(s) => assert_eq(s.uri, "a.feature")
_ => panic()
}
let back : Envelope = @json.from_json(env.to_json()) catch { _ => panic() }
match back {
Source(s2) => assert_eq(s2.uri, "a.feature")
_ => panic()
}
}
///|
test "envelope attachment roundtrip" {
let raw = "{\"attachment\":{\"body\":\"data\",\"contentEncoding\":\"BASE64\",\"mediaType\":\"image/png\"}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
Attachment(a) => assert_eq(a.mediaType, "image/png")
_ => panic()
}
let back : Envelope = @json.from_json(env.to_json()) catch { _ => panic() }
match back {
Attachment(a) => assert_eq(a.body, "data")
_ => panic()
}
}
///|
test "envelope external attachment roundtrip" {
let raw = "{\"externalAttachment\":{\"url\":\"https://example.com/f.txt\",\"mediaType\":\"text/plain\"}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
ExternalAttachment(e) => assert_eq(e.url, "https://example.com/f.txt")
_ => panic()
}
let back : Envelope = @json.from_json(env.to_json()) catch { _ => panic() }
match back {
ExternalAttachment(e) => assert_eq(e.mediaType, "text/plain")
_ => panic()
}
}
///|
test "envelope hook roundtrip" {
let raw = "{\"hook\":{\"id\":\"h2\",\"sourceReference\":{}}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
Hook(h) => assert_eq(h.id, "h2")
_ => panic()
}
let back : Envelope = @json.from_json(env.to_json()) catch { _ => panic() }
match back {
Hook(h) => assert_eq(h.id, "h2")
_ => panic()
}
}
///|
test "envelope step definition roundtrip" {
let raw = "{\"stepDefinition\":{\"id\":\"sd2\",\"pattern\":{\"source\":\"^given$\",\"type\":\"REGULAR_EXPRESSION\"},\"sourceReference\":{}}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
StepDefinition(sd) => assert_eq(sd.id, "sd2")
_ => panic()
}
let back : Envelope = @json.from_json(env.to_json()) catch { _ => panic() }
match back {
StepDefinition(sd) => assert_eq(sd.id, "sd2")
_ => panic()
}
}
///|
test "envelope parameter type roundtrip" {
let raw = "{\"parameterType\":{\"id\":\"pt2\",\"name\":\"int\",\"preferForRegularExpressionMatch\":false,\"regularExpressions\":[\"\\\\d+\"],\"useForSnippets\":true}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
ParameterType(pt) => assert_eq(pt.name, "int")
_ => panic()
}
let back : Envelope = @json.from_json(env.to_json()) catch { _ => panic() }
match back {
ParameterType(pt) => assert_eq(pt.name, "int")
_ => panic()
}
}
///|
test "envelope suggestion roundtrip" {
let raw = "{\"suggestion\":{\"id\":\"sug2\",\"pickleStepId\":\"ps2\",\"snippets\":[{\"language\":\"ruby\",\"code\":\"Given\"}]}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
Suggestion(s) => assert_eq(s.id, "sug2")
_ => panic()
}
let back : Envelope = @json.from_json(env.to_json()) catch { _ => panic() }
match back {
Suggestion(s) => assert_eq(s.snippets[0].language, "ruby")
_ => panic()
}
}
///|
test "envelope test run hook started roundtrip" {
let raw = "{\"testRunHookStarted\":{\"id\":\"trhs2\",\"testRunStartedId\":\"trs2\",\"hookId\":\"h2\",\"timestamp\":{\"seconds\":200,\"nanos\":0}}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
TestRunHookStarted(t) => assert_eq(t.id, "trhs2")
_ => panic()
}
let back : Envelope = @json.from_json(env.to_json()) catch { _ => panic() }
match back {
TestRunHookStarted(t) => assert_eq(t.hookId, "h2")
_ => panic()
}
}
///|
test "envelope test run hook finished roundtrip" {
let raw = "{\"testRunHookFinished\":{\"testRunHookStartedId\":\"trhs3\",\"result\":{\"duration\":{\"seconds\":0,\"nanos\":500},\"status\":\"FAILED\"},\"timestamp\":{\"seconds\":300,\"nanos\":0}}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
TestRunHookFinished(t) => assert_eq(t.testRunHookStartedId, "trhs3")
_ => panic()
}
let back : Envelope = @json.from_json(env.to_json()) catch { _ => panic() }
match back {
TestRunHookFinished(t) =>
match t.result.status {
Failed => ()
_ => panic()
}
_ => panic()
}
}
///|
test "envelope gherkin document roundtrip" {
let raw = "{\"gherkinDocument\":{\"comments\":[],\"feature\":{\"location\":{\"line\":1},\"tags\":[],\"language\":\"en\",\"keyword\":\"Feature\",\"name\":\"X\",\"description\":\"\",\"children\":[]}}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
GherkinDocument(doc) => {
guard doc.feature is Some(f)
assert_eq(f.name, "X")
}
_ => panic()
}
let back : Envelope = @json.from_json(env.to_json()) catch { _ => panic() }
match back {
GherkinDocument(_) => ()
_ => panic()
}
}
///|
test "envelope pickle roundtrip" {
let raw = "{\"pickle\":{\"id\":\"p2\",\"uri\":\"a.feature\",\"name\":\"Q\",\"language\":\"en\",\"steps\":[],\"tags\":[],\"astNodeIds\":[\"x\"]}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
Pickle(p) => assert_eq(p.name, "Q")
_ => panic()
}
let back : Envelope = @json.from_json(env.to_json()) catch { _ => panic() }
match back {
Pickle(p) => assert_eq(p.id, "p2")
_ => panic()
}
}
///|
test "envelope test case roundtrip" {
let raw = "{\"testCase\":{\"id\":\"tc3\",\"pickleId\":\"p3\",\"testSteps\":[{\"id\":\"ts3\"}]}}"
let json = @json.parse(raw) catch { _ => panic() }
let env : Envelope = @json.from_json(json) catch { _ => panic() }
match env {
TestCase(tc) => assert_eq(tc.id, "tc3")
_ => panic()
}
let back : Envelope = @json.from_json(env.to_json()) catch { _ => panic() }
match back {
TestCase(tc) => assert_eq(tc.pickleId, "p3")
_ => panic()
}
}