Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added support for Attachments (aka Embedddings) #623

Merged
merged 14 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ Gopkg.toml
.idea
.vscode

_artifacts
_artifacts

vendor
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
## [v0.14.1]

### Added
- Provide support for attachments / embeddings - ([623](https://github.com/cucumber/godog/pull/623) - [johnlon](https://github.com/johnlon))
- Provide testing.T-compatible interface on test context, allowing usage of assertion libraries such as testify's assert/require - ([571](https://github.com/cucumber/godog/pull/571) - [mrsheepuk](https://github.com/mrsheepuk))
- Created releasing guidelines - ([608](https://github.com/cucumber/godog/pull/608) - [glibas](https://github.com/glibas))

Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -580,3 +580,6 @@ A simple example can be [found here](/_examples/custom-formatter).
[contributing guide]: https://github.com/cucumber/godog/blob/main/CONTRIBUTING.md
[releasing guide]: https://github.com/cucumber/godog/blob/main/RELEASING.md
[community Slack]: https://cucumber.io/community#slack



37 changes: 30 additions & 7 deletions internal/formatters/fmt_cucumber.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package formatters
*/

import (
"encoding/base64"
"encoding/json"
"fmt"
"io"
Expand Down Expand Up @@ -139,14 +140,21 @@ type cukeMatch struct {
Location string `json:"location"`
}

type cukeEmbedding struct {
Name string `json:"name"`
MimeType string `json:"mime_type"`
Data string `json:"data"`
}

type cukeStep struct {
Keyword string `json:"keyword"`
Name string `json:"name"`
Line int `json:"line"`
Docstring *cukeDocstring `json:"doc_string,omitempty"`
Match cukeMatch `json:"match"`
Result cukeResult `json:"result"`
DataTable []*cukeDataTableRow `json:"rows,omitempty"`
Keyword string `json:"keyword"`
Name string `json:"name"`
Line int `json:"line"`
Docstring *cukeDocstring `json:"doc_string,omitempty"`
Match cukeMatch `json:"match"`
Result cukeResult `json:"result"`
DataTable []*cukeDataTableRow `json:"rows,omitempty"`
Embeddings []*cukeEmbedding `json:"embeddings,omitempty"`
Johnlon marked this conversation as resolved.
Show resolved Hide resolved
}

type cukeDataTableRow struct {
Expand Down Expand Up @@ -294,6 +302,21 @@ func (f *Cuke) buildCukeStep(pickle *messages.Pickle, stepResult models.PickleSt
cukeStep.Match.Location = fmt.Sprintf("%s:%d", pickle.Uri, step.Location.Line)
}

if stepResult.Attachments != nil {
attachments := []*cukeEmbedding{}

for _, a := range stepResult.Attachments {
attachments = append(attachments, &cukeEmbedding{
Name: a.Name,
Data: base64.RawStdEncoding.EncodeToString(a.Data),
MimeType: a.MimeType,
})
}

if len(attachments) > 0 {
cukeStep.Embeddings = attachments
}
}
return cukeStep
}

Expand Down
25 changes: 25 additions & 0 deletions internal/formatters/fmt_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,31 @@ func (f *Events) step(pickle *messages.Pickle, pickleStep *messages.PickleStep)
if pickleStepResult.Err != nil {
errMsg = pickleStepResult.Err.Error()
}

if pickleStepResult.Attachments != nil {
for _, attachment := range pickleStepResult.Attachments {

f.event(&struct {
Event string `json:"event"`
Location string `json:"location"`
Timestamp int64 `json:"timestamp"`
ContentEncoding string `json:"contentEncoding"`
FileName string `json:"fileName"`
MimeType string `json:"mimeType"`
Body string `json:"body"`
}{
"Attachment",
fmt.Sprintf("%s:%d", pickle.Uri, step.Location.Line),
utils.TimeNowFunc().UnixNano() / nanoSec,
messages.AttachmentContentEncoding_BASE64.String(),
attachment.Name,
attachment.MimeType,
string(attachment.Data),
})

}
}

f.event(&struct {
Event string `json:"event"`
Location string `json:"location"`
Expand Down
32 changes: 26 additions & 6 deletions internal/formatters/fmt_output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package formatters_test

import (
"bytes"
"context"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"regexp"
"strings"
"testing"

Expand All @@ -24,9 +25,7 @@ func Test_FmtOutput(t *testing.T) {

featureFiles, err := listFmtOutputTestsFeatureFiles()
require.Nil(t, err)

formatters := []string{"cucumber", "events", "junit", "pretty", "progress", "junit,pretty"}

for _, fmtName := range formatters {
for _, featureFile := range featureFiles {
testName := fmt.Sprintf("%s/%s", fmtName, featureFile)
Expand Down Expand Up @@ -65,6 +64,7 @@ func fmtOutputTest(fmtName, testName, featureFilePath string) func(*testing.T) {
ctx.Step(`^(?:a )?pending step$`, pendingStepDef)
ctx.Step(`^(?:a )?passing step$`, passingStepDef)
ctx.Step(`^odd (\d+) and even (\d+) number$`, oddEvenStepDef)
ctx.Step(`^(?:a )?a step with attachment$`, stepWithAttachment)
}

return func(t *testing.T) {
Expand All @@ -74,7 +74,7 @@ func fmtOutputTest(fmtName, testName, featureFilePath string) func(*testing.T) {
t.Skipf("Couldn't find expected output file %q", expectOutputPath)
}

expectedOutput, err := ioutil.ReadFile(expectOutputPath)
expectedOutput, err := os.ReadFile(expectOutputPath)
require.NoError(t, err)

var buf bytes.Buffer
Expand All @@ -92,12 +92,23 @@ func fmtOutputTest(fmtName, testName, featureFilePath string) func(*testing.T) {
Options: &opts,
}.Run()

expected := string(expectedOutput)
actual := buf.String()
// normalise on unix line ending so expected vs actual works cross platform
expected := normalise(string(expectedOutput))
actual := normalise(buf.String())
assert.Equalf(t, expected, actual, "path: %s", expectOutputPath)
}
}

func normalise(s string) string {

m := regexp.MustCompile("fmt_output_test.go:[0-9]+")
normalised := m.ReplaceAllString(s, "fmt_output_test.go:XXX")
normalised = strings.Replace(normalised, "\r\n", "\n", -1)
normalised = strings.Replace(normalised, "\\r\\n", "\\n", -1)

return normalised
}

func passingStepDef() error { return nil }

func oddEvenStepDef(odd, even int) error { return oddOrEven(odd, even) }
Expand All @@ -115,3 +126,12 @@ func oddOrEven(odd, even int) error {
func pendingStepDef() error { return godog.ErrPending }

func failingStepDef() error { return fmt.Errorf("step failed") }

func stepWithAttachment(ctx context.Context) (context.Context, error) {
ctxOut := godog.Attach(ctx,
godog.Attachment{Body: []byte("TheData1"), FileName: "TheFilename1", MediaType: "text/plain"},
godog.Attachment{Body: []byte("TheData2"), FileName: "TheFilename2", MediaType: "text/plain"},
)

return ctxOut, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[
{
"uri": "formatter-tests/features/scenario_with_attachment.feature",
"id": "scenario-with-attachment",
"keyword": "Feature",
"name": "scenario with attachment",
"description": " describes\n an attachment\n feature",
"line": 1,
"elements": [
{
"id": "scenario-with-attachment;step-with-attachment",
"keyword": "Scenario",
"name": "step with attachment",
"description": "",
"line": 6,
"type": "scenario",
"steps": [
{
"keyword": "Given ",
"name": "a step with attachment",
"line": 7,
"match": {
"location": "fmt_output_test.go:119"
},
"result": {
"status": "passed",
"duration": 0
},
"embeddings": [
{
"name": "TheFilename1",
"mime_type": "text/plain",
"data": "VGhlRGF0YTE"
},
{
"name": "TheFilename2",
"mime_type": "text/plain",
"data": "VGhlRGF0YTI"
}
]
}
]
}
]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{"event":"TestRunStarted","version":"0.1.0","timestamp":-6795364578871,"suite":"events"}
{"event":"TestSource","location":"formatter-tests/features/scenario_with_attachment.feature:1","source":"Feature: scenario with attachment\n describes\n an attachment\n feature\n\n Scenario: step with attachment\n Given a step with attachment\n"}
{"event":"TestCaseStarted","location":"formatter-tests/features/scenario_with_attachment.feature:6","timestamp":-6795364578871}
{"event":"StepDefinitionFound","location":"formatter-tests/features/scenario_with_attachment.feature:7","definition_id":"fmt_output_test.go:XXX -\u003e github.com/cucumber/godog/internal/formatters_test.stepWithAttachment","arguments":[]}
{"event":"TestStepStarted","location":"formatter-tests/features/scenario_with_attachment.feature:7","timestamp":-6795364578871}
{"event":"Attachment","location":"formatter-tests/features/scenario_with_attachment.feature:7","timestamp":-6795364578871,"contentEncoding":"BASE64","fileName":"TheFilename1","mimeType":"text/plain","body":"TheData1"}
{"event":"Attachment","location":"formatter-tests/features/scenario_with_attachment.feature:7","timestamp":-6795364578871,"contentEncoding":"BASE64","fileName":"TheFilename2","mimeType":"text/plain","body":"TheData2"}
{"event":"TestStepFinished","location":"formatter-tests/features/scenario_with_attachment.feature:7","timestamp":-6795364578871,"status":"passed"}
{"event":"TestCaseFinished","location":"formatter-tests/features/scenario_with_attachment.feature:6","timestamp":-6795364578871,"status":"passed"}
{"event":"TestRunFinished","status":"passed","timestamp":-6795364578871,"snippets":"","memory":""}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Feature: scenario with attachment
describes
an attachment
feature

Scenario: step with attachment
Given a step with attachment
11 changes: 11 additions & 0 deletions internal/models/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@
StartedAt time.Time
}

// PickleAttachment ...
type PickleAttachment struct {
Johnlon marked this conversation as resolved.
Show resolved Hide resolved
Name string
MimeType string
Data []byte
}

// PickleStepResult ...
type PickleStepResult struct {
Status StepResultStatus
Expand All @@ -28,13 +35,16 @@
PickleStepID string

Def *StepDefinition

Attachments []*PickleAttachment
Johnlon marked this conversation as resolved.
Show resolved Hide resolved
}

// NewStepResult ...
func NewStepResult(
status StepResultStatus,
pickleID, pickleStepID string,
match *StepDefinition,
attachments []*PickleAttachment,
err error,
) PickleStepResult {
return PickleStepResult{
Expand All @@ -44,6 +54,7 @@
PickleID: pickleID,
PickleStepID: pickleStepID,
Def: match,
Attachments: attachments,

Check warning on line 57 in internal/models/results.go

View check run for this annotation

Codecov / codecov/patch

internal/models/results.go#L57

Added line #L57 was not covered by tests
}
}

Expand Down
Loading
Loading