diff --git a/.travis.yml b/.travis.yml index 493f33e..c23d828 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ services: go: - "1.10" env: - - PATH=$HOME/gopath/bin:$PATH APPPATH=$HOME/gopath/src/github.com/bluehoodie/smoke/ ENVTOKEN=token235 COVERALLS_TOKEN=PPZJ56Ts2op5e2dlIRIhO82p6FPP95mZ1 + - PATH=$HOME/gopath/bin:$PATH APPPATH=$HOME/gopath/src/github.com/bluehoodie/smoke/ ENVTOKEN=token235 before_install: # mock web service - docker pull bluehoodie/httpbin @@ -18,8 +18,6 @@ before_script: # install dependencies - go get -u github.com/golang/dep/cmd/dep - go get -u golang.org/x/lint/golint - - go get golang.org/x/tools/cmd/cover - - go get github.com/mattn/goveralls - dep ensure - go test -race -v `go list ./... | grep -v -e /vendor/ -e /mock/` - go list ./... | grep -v /vendor/ | xargs -L1 golint -set_exit_status @@ -32,9 +30,6 @@ script: after_script: - docker stop httpbin after_success: - - go get github.com/goreleaser/goreleaser - - go test ./... -v -covermode=count -coverprofile=coverage.out - - $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN - cd $APPPATH - if [[ $TRAVIS_PULL_REQUEST == "false" ]] && [[ $TRAVIS_BRANCH == "master" ]]; then docker login -u="$DOCKERHUB_LOGIN" -p="$DOCKERHUB_PASSWORD"; fi - if [[ $TRAVIS_PULL_REQUEST == "false" ]] && [[ $TRAVIS_BRANCH == "master" ]]; then make publish; fi diff --git a/Gopkg.lock b/Gopkg.lock index 718dbd7..7d70708 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -2,68 +2,94 @@ [[projects]] + digest = "1:56c130d885a4aacae1dd9c7b71cfe39912c7ebc1ff7d2b46083c8812996dc43b" name = "github.com/davecgh/go-spew" packages = ["spew"] + pruneopts = "" revision = "346938d642f2ec3594ed81d874461961cd0faa76" version = "v1.1.0" [[projects]] + digest = "1:d7d69c103aba5ea229451115b28ca06d061e3861b2f44bcd0100cbc65659c4d9" name = "github.com/fatih/color" packages = ["."] + pruneopts = "" revision = "507f6050b8568533fb3f5504de8e5205fa62a114" version = "v1.6.0" [[projects]] + digest = "1:550e69376be9a028e7a039090d635e949134873c651a74a95a8896552db372b8" name = "github.com/jessevdk/go-flags" packages = ["."] + pruneopts = "" revision = "96dc06278ce32a0e9d957d590bb987c81ee66407" version = "v1.3.0" [[projects]] + digest = "1:9ea83adf8e96d6304f394d40436f2eb44c1dc3250d223b74088cc253a6cd0a1c" name = "github.com/mattn/go-colorable" packages = ["."] + pruneopts = "" revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" version = "v0.0.9" [[projects]] + digest = "1:78229b46ddb7434f881390029bd1af7661294af31f6802e0e1bedaad4ab0af3c" name = "github.com/mattn/go-isatty" packages = ["."] + pruneopts = "" revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" version = "v0.0.3" [[projects]] + digest = "1:7365acd48986e205ccb8652cc746f09c8b7876030d53710ea6ef7d0bd0dcd7ca" name = "github.com/pkg/errors" packages = ["."] + pruneopts = "" revision = "645ef00459ed84a119197bfb8d8205042c6df63d" version = "v0.8.0" [[projects]] + digest = "1:256484dbbcd271f9ecebc6795b2df8cad4c458dd0f5fd82a8c2fa0c29f233411" name = "github.com/pmezard/go-difflib" packages = ["difflib"] + pruneopts = "" revision = "792786c7400a136282c1664665ae0a8db921c6c2" version = "v1.0.0" [[projects]] + digest = "1:a30066593578732a356dc7e5d7f78d69184ca65aeeff5939241a3ab10559bb06" name = "github.com/stretchr/testify" packages = ["assert"] + pruneopts = "" revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" version = "v1.2.1" [[projects]] branch = "master" + digest = "1:0a0c73aced706c77f4f128971976b0ee94db7bdcc95b6088bda9e72594598634" name = "golang.org/x/sys" packages = ["unix"] + pruneopts = "" revision = "dd2ff4accc098aceecb86b36eaa7829b2a17b1c9" [[projects]] + digest = "1:5fe876313b07628905b2181e537faabe45032cb9c79c01b49b51c25a0a40040d" name = "gopkg.in/yaml.v2" packages = ["."] + pruneopts = "" revision = "7f97868eec74b32b0982dd158a51a446d1da7eb5" version = "v2.1.1" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "143c4df8658a8e7fa62a7bd0db0317ca5e18107fdceeb977d1601f25de26b6bd" + input-imports = [ + "github.com/fatih/color", + "github.com/jessevdk/go-flags", + "github.com/pkg/errors", + "github.com/stretchr/testify/assert", + "gopkg.in/yaml.v2", + ] solver-name = "gps-cdcl" solver-version = 1 diff --git a/README.md b/README.md index 3b6ab8e..fd5d397 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,6 @@ [![Build Status](https://travis-ci.org/bluehoodie/smoke.svg?branch=master)](https://travis-ci.org/bluehoodie/smoke) [![Go Report Card](https://goreportcard.com/badge/github.com/bluehoodie/smoke)](https://goreportcard.com/report/github.com/bluehoodie/smoke) -[![Coverage Status](https://coveralls.io/repos/github/Tkanos/smoke/badge.svg?branch=master)](https://coveralls.io/github/Tkanos/smoke?branch=master) - A simple application to write and run smoke tests for RESTful APIs. diff --git a/tester/tester.go b/internal/tester/tester.go similarity index 78% rename from tester/tester.go rename to internal/tester/tester.go index fc390c3..bbc9507 100644 --- a/tester/tester.go +++ b/internal/tester/tester.go @@ -2,11 +2,15 @@ package tester import ( "bytes" + "encoding/json" "fmt" + "github.com/pkg/errors" + "gopkg.in/yaml.v2" "io" "io/ioutil" "net/http" "os" + "path" "regexp" "strings" @@ -39,16 +43,45 @@ type Contract struct { ExpectedHTTPCode int `json:"http_code_is" yaml:"http_code_is"` ExpectedResponseBody string `json:"response_body_contains" yaml:"response_body_contains"` - ExpectedResponses []string `json:"response_contains" yaml:"response_contains"` + ExpectedResponses []string `json:"response_contains" yaml:"response_contains"` ExpectedHeaders map[string]string `json:"response_headers_is" yaml:"response_headers_is"` } - // Test represents the data for a full test suite type Test struct { - Globals map[string]string `json:"globals" yaml:"globals"` + Globals map[string]string `json:"globals" yaml:"globals"` + Contracts []Contract `json:"contracts" yaml:"contracts"` +} + +// NewTest returns an initialized *Test and any error encountered along the way +func NewTest(inputFile string) (*Test, error) { + data, err := ioutil.ReadFile(inputFile) + if err != nil { + return nil, errors.Wrapf(err, "could not read test file %v", inputFile) + } + + t := Test{} + if err := unmarshal(inputFile, data, &t); err != nil { + return nil, errors.Wrap(err, "could not unmarshal test data") + } + + t.init() - Contracts []Contract `json:"contracts" yaml:"contracts"` + return &t, nil +} + +func (t *Test) init() { + if t == nil || len(t.Contracts) == 0 { + return + } + + for _, c := range t.Contracts { + if c.ExpectedResponseBody == "" { + continue + } + + c.ExpectedResponses = append(c.ExpectedResponses, c.ExpectedResponseBody) + } } // Runner is the primary struct of this package and is responsible for running the test suite @@ -58,7 +91,7 @@ type Runner struct { client *http.Client - test Test + test *Test url string } @@ -83,7 +116,7 @@ func WithHTTPClient(client *http.Client) Option { } // NewRunner returns a *Runner for a given url and Test. -func NewRunner(url string, test Test, opts ...Option) *Runner { +func NewRunner(url string, test *Test, opts ...Option) *Runner { runner := &Runner{ url: url, test: test, @@ -172,8 +205,8 @@ func failure(out io.Writer, name, format string, args ...interface{}) { func createAndSendRequest(contract Contract, url string, client *http.Client) (*http.Response, error) { // create request - path := strings.Join([]string{url, contract.Path}, "") - req, err := http.NewRequest(strings.ToUpper(contract.Method), path, strings.NewReader(contract.Body)) + uri := strings.Join([]string{url, contract.Path}, "") + req, err := http.NewRequest(strings.ToUpper(contract.Method), uri, strings.NewReader(contract.Body)) if err != nil { return nil, fmt.Errorf("could not create http request: %v", err) } @@ -206,7 +239,7 @@ func validateResponseBody(contract Contract, body []byte) error { if len(contract.ExpectedResponses) == 0 { return nil } - + for _, r := range contract.ExpectedResponses { // check if it is a regexp if strings.HasPrefix(r, "r/") { @@ -221,7 +254,7 @@ func validateResponseBody(contract Contract, body []byte) error { return fmt.Errorf("expected response not found in the body") } } - + return nil } @@ -239,3 +272,19 @@ func validateHeaders(contract Contract, resp *http.Response) error { return nil } + +func unmarshal(filename string, in []byte, out interface{}) error { + var unmarshalError error + + ext := strings.Trim(path.Ext(filename), ".") + switch ext { + case "yaml": + fallthrough + case "yml": + unmarshalError = yaml.Unmarshal(in, out) + default: + unmarshalError = json.Unmarshal(in, out) + } + + return unmarshalError +} diff --git a/tester/variables.go b/internal/tester/variables.go similarity index 81% rename from tester/variables.go rename to internal/tester/variables.go index 666d50e..424aba4 100644 --- a/tester/variables.go +++ b/internal/tester/variables.go @@ -94,9 +94,9 @@ func parseOutputs(runner *Runner, contract *Contract, body []byte) (err error) { s := strings.Split(value, ".") var result string if len(s) > 1 { - switch strings.ToUpper(s[0]) { - case "JSON": - result, err = jsonParser(value, s[1:], body) + switch strings.ToLower(s[0]) { + case "json": + result, err = parseJSON(value, s[1:], body) if err != nil { return } @@ -109,23 +109,23 @@ func parseOutputs(runner *Runner, contract *Contract, body []byte) (err error) { return nil } -func jsonParser(format string, field []string, body []byte) (value string, err error) { - if body == nil || field == nil || len(field) == 0 { - return "", fmt.Errorf("Bad Parameter") +func parseJSON(format string, fields []string, body []byte) (value string, err error) { + if body == nil || fields == nil || len(fields) == 0 { + return "", fmt.Errorf("bad parameter") } begin := 0 var next interface{} // If it begins by a [], we should extract the info from an array - if string(field[0][0]) == "[" { + if string(fields[0][0]) == "[" { var arr []interface{} err = json.Unmarshal(body, &arr) if err != nil { return } - v := extractValueFromJSONArray(field[begin], arr) - if begin == len(field)-1 { // if it is the value expected + v := extractValueFromJSONArray(fields[begin], arr) + if begin == len(fields)-1 { // if it is the value expected value = fmt.Sprint(v) return } @@ -147,17 +147,17 @@ func jsonParser(format string, field []string, body []byte) (value string, err e } tmp := jsonMap - for i := begin; i < len(field); i++ { - if i == len(field)-1 { - if string(field[i][len(field[i])-1]) == "]" { // It's an array and field[i] is in the format "param[number]" - v := extractValueFromJSONMap(field[i], tmp) + for i := begin; i < len(fields); i++ { + if i == len(fields)-1 { + if string(fields[i][len(fields[i])-1]) == "]" { // It's an array and fields[i] is in the format "param[number]" + v := extractValueFromJSONMap(fields[i], tmp) if v != nil { value = fmt.Sprint(v) return } } // value - if val, ok := tmp[field[i]]; ok { + if val, ok := tmp[fields[i]]; ok { value = fmt.Sprint(val) return } @@ -167,10 +167,10 @@ func jsonParser(format string, field []string, body []byte) (value string, err e var o interface{} - if string(field[i][len(field[i])-1]) == "]" { // It's an array and field[i] is in the format "param[number]" - o = extractValueFromJSONMap(field[i], tmp) + if string(fields[i][len(fields[i])-1]) == "]" { // It's an array and fields[i] is in the format "param[number]" + o = extractValueFromJSONMap(fields[i], tmp) } else { - if val, ok := tmp[field[i]]; ok { + if val, ok := tmp[fields[i]]; ok { o = val } else { return "", fmt.Errorf("value not present in the json object %s", format) @@ -178,7 +178,6 @@ func jsonParser(format string, field []string, body []byte) (value string, err e } tmp = o.(map[string]interface{}) - } return diff --git a/tester/variables_test.go b/internal/tester/variables_test.go similarity index 74% rename from tester/variables_test.go rename to internal/tester/variables_test.go index 19c5dfc..273aad2 100644 --- a/tester/variables_test.go +++ b/internal/tester/variables_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" ) -var extractmaptt = []struct { +var mapExtractTests = []struct { m map[string]interface{} key string expected interface{} @@ -32,7 +32,7 @@ var extractmaptt = []struct { expected: nil, }, { - description: "should send nil if there is no number formated string between [] on the key", + description: "should send nil if there is no number formatted string between [] on the key", m: make(map[string]interface{}), key: "param[abc]", expected: nil, @@ -56,16 +56,14 @@ var extractmaptt = []struct { } func TestExtractValueFromJSONMap(t *testing.T) { - for _, tt := range extractmaptt { - //act + for _, tt := range mapExtractTests { result := extractValueFromJSONMap(tt.key, tt.m) - //arrange assert.Equal(t, tt.expected, result, tt.description) } } -var jsonParsertt = []struct { +var jsonParserTests = []struct { json string conf string keys []string @@ -74,7 +72,7 @@ var jsonParsertt = []struct { description string }{ { - description: "should have an error when no field parameter", + description: "should have an error when no field parameter is defined", conf: "A", keys: []string{}, json: `{ "A":1 }`, @@ -90,7 +88,7 @@ var jsonParsertt = []struct { expectedValue: "", }, { - description: "should have an error when no body parameter", + description: "should have an error when no body parameter is defined", conf: "A", keys: []string{"A"}, json: "", @@ -98,7 +96,7 @@ var jsonParsertt = []struct { expectedValue: "", }, { - description: "should have an error when no json", + description: "should have an error when no json is defined", json: "Hello World", conf: "A", keys: []string{"A"}, @@ -106,7 +104,7 @@ var jsonParsertt = []struct { expectedValue: "", }, { - description: "should have an error when value is not present in the middle of the json", + description: "should have an error when value is not present in the json", conf: "C.D", keys: []string{"C", "D"}, json: `{ "A": { "B": 1 } }`, @@ -122,7 +120,7 @@ var jsonParsertt = []struct { expectedValue: "", }, { - description: "should works when the format is A", + description: "should work when the format is A", conf: "A", keys: []string{"A"}, json: `{ "A":1 }`, @@ -130,7 +128,7 @@ var jsonParsertt = []struct { expectedValue: "1", }, { - description: "should works when the format is A.B", + description: "should work when the format is A.B", conf: "A.B", keys: []string{"A", "B"}, json: `{ "A": { "B": 1 } }`, @@ -138,7 +136,7 @@ var jsonParsertt = []struct { expectedValue: "1", }, { - description: "should works when the format is A.B[0]", + description: "should work when the format is A.B[0]", conf: "A.B[0]", keys: []string{"A", "B[0]"}, json: `{ "A": { "B": [1,2,3] } }`, @@ -146,7 +144,7 @@ var jsonParsertt = []struct { expectedValue: "1", }, { - description: "should works when the format is A.B[1].C", + description: "should work when the format is A.B[1].C", conf: "A.B[1].C", keys: []string{"A", "B[1]", "C"}, json: `{ "A": { "B": [{"C":1},{"C":2}] } }`, @@ -154,7 +152,7 @@ var jsonParsertt = []struct { expectedValue: "2", }, { - description: "should works when the format is [2]", + description: "should work when the format is [2]", conf: "[2]", keys: []string{"[2]"}, json: `[1,2,3]`, @@ -162,7 +160,7 @@ var jsonParsertt = []struct { expectedValue: "3", }, { - description: "should works when the format is [0].A", + description: "should work when the format is [0].A", conf: "[0].A", keys: []string{"[0]", "A"}, json: `[ {"A":1}, {"A":2} ]`, @@ -180,17 +178,15 @@ var jsonParsertt = []struct { } func TestJsonParser(t *testing.T) { - for _, tt := range jsonParsertt { - //act - v, err := jsonParser(tt.conf, tt.keys, []byte(tt.json)) + for _, tt := range jsonParserTests { + v, err := parseJSON(tt.conf, tt.keys, []byte(tt.json)) - //assert assert.True(t, (err != nil) == tt.expectedError, tt.description) assert.Equal(t, tt.expectedValue, v, tt.description) } } -var extractarraytt = []struct { +var arrayExtractTests = []struct { key string arr []interface{} expected interface{} @@ -209,7 +205,7 @@ var extractarraytt = []struct { expected: nil, }, { - description: "should works when all is correct", + description: "should work when all is correct", key: "[0]", arr: []interface{}{ "Hello", @@ -219,11 +215,9 @@ var extractarraytt = []struct { } func TestExtractValueFromJSONArray(t *testing.T) { - for _, tt := range extractarraytt { - //act + for _, tt := range arrayExtractTests { v := extractValueFromJSONArray(tt.key, tt.arr) - //assert assert.Equal(t, tt.expected, v, tt.description) } } @@ -242,43 +236,41 @@ var parseOtt = []struct { Outputs: make(map[string]string), }, err: false, - description: "It should not return an error if there are no outputs", + description: "should not return an error if there are no outputs", }, { contract: &Contract{ Outputs: map[string]string{"value": "NOT_MAPPED.whatever"}, }, err: true, - description: "It should return an error if there are outputs that does not begin by what is expected (JSON)", + description: "should return an error if there are outputs that does not begin by what is expected (JSON)", }, { contract: &Contract{ Outputs: map[string]string{"value": "JSON.A"}, }, - runner: &Runner{test: Test{Globals: make(map[string]string)}}, + runner: &Runner{test: &Test{Globals: make(map[string]string)}}, body: []byte(`{"A": 1 }`), err: false, expectedKey: "value", expectedValue: "1", - description: "Runner should have an value as output", + description: "runner should have an value as output", }, { contract: &Contract{ Outputs: map[string]string{"value": "JSON.A"}, }, - runner: &Runner{test: Test{Globals: make(map[string]string)}}, + runner: &Runner{test: &Test{Globals: make(map[string]string)}}, body: []byte(`OBVIOUSLY NOT A JSON`), err: true, - description: "It should return an error if the body does not match with what is exected", + description: "should return an error if the body does not match with what is expected", }, } func TestParseOutputs(t *testing.T) { for _, tt := range parseOtt { - //act err := parseOutputs(tt.runner, tt.contract, tt.body) - //assert assert.True(t, (err != nil) == tt.err, tt.description) if tt.expectedKey != "" && err == nil { @@ -290,7 +282,7 @@ func TestParseOutputs(t *testing.T) { } -var replaceVartt = []struct { +var variableReplacementTests = []struct { s string contract *Contract runner *Runner @@ -303,55 +295,54 @@ var replaceVartt = []struct { s: "NO PATTERN", err: false, expected: "NO PATTERN", - description: "If there are no value to replace it should return the string in output", + description: "should return the string in output", }, { s: "::local::", err: false, contract: &Contract{Locals: map[string]string{"local": "1"}}, - runner: &Runner{test: Test{Globals: map[string]string{}}}, + runner: &Runner{test: &Test{Globals: map[string]string{}}}, expected: "1", - description: "If should replace the input value by the local one", + description: "should replace the input value by the local one", }, { s: "::global::", err: false, contract: &Contract{Locals: map[string]string{}}, - runner: &Runner{test: Test{Globals: map[string]string{"global": "1"}}}, + runner: &Runner{test: &Test{Globals: map[string]string{"global": "1"}}}, expected: "1", - description: "If should replace the input value by the global one", + description: "should replace the input value by the global one", }, { s: "::env::", err: false, contract: &Contract{Locals: map[string]string{}}, - runner: &Runner{test: Test{Globals: map[string]string{}}}, + runner: &Runner{test: &Test{Globals: map[string]string{}}}, env: map[string]string{"ENV": "1"}, expected: "1", - description: "If should replace the input value by the env one", + description: "should replace the input value by the env one", }, { s: "::not_found::", contract: &Contract{Locals: map[string]string{}}, - runner: &Runner{test: Test{Globals: map[string]string{}}}, + runner: &Runner{test: &Test{Globals: map[string]string{}}}, expected: "::not_found::", err: true, - description: "If should send an error if the value is not on local, global neither env variables", + description: "should send an error if the value is not on local, global neither env variables", }, { s: "::local::_::global::_::env::", err: false, contract: &Contract{Locals: map[string]string{"local": "1"}}, - runner: &Runner{test: Test{Globals: map[string]string{"global": "2"}}}, + runner: &Runner{test: &Test{Globals: map[string]string{"global": "2"}}}, env: map[string]string{"ENV": "3"}, expected: "1_2_3", - description: "If should replace all the values if there are many ", + description: "should replace all the values if there are many ", }, } func TestReplaceVariables(t *testing.T) { - for _, tt := range replaceVartt { - //arrange + for _, tt := range variableReplacementTests { if tt.env != nil && len(tt.env) > 0 { // Define env variables for key, value := range tt.env { @@ -359,10 +350,8 @@ func TestReplaceVariables(t *testing.T) { } } - //act s, err := replaceVariables(tt.runner, tt.contract, tt.s) - //assert assert.True(t, (err != nil) == tt.err, tt.description) assert.Equal(t, tt.expected, s, tt.description) } diff --git a/main.go b/main.go index e0ffb88..69051d1 100644 --- a/main.go +++ b/main.go @@ -1,24 +1,20 @@ package main import ( - "encoding/json" "fmt" - "io/ioutil" "net/http" "os" - "path" - "strings" "time" - "github.com/bluehoodie/smoke/tester" + "github.com/bluehoodie/smoke/internal/tester" + "github.com/jessevdk/go-flags" - yaml "gopkg.in/yaml.v2" ) var opts struct { Verbose bool `short:"v" long:"verbose" description:"print out full report including successful results"` - File string `short:"f" long:"file" default:"./smoke_test.json" description:"file containing the test definition"` - URL string `short:"u" long:"url" default:"http://localhost" description:"url endpoint to test"` + File string `short:"f" long:"file" default:"./smoke_test.yaml" description:"file containing the test definition"` + URL string `short:"u" long:"url" default:"https://httpbin.org" description:"url endpoint to test"` Port int `short:"p" long:"port" description:"port the service is running on"` Timeout int `short:"t" long:"timeout" default:"1" description:"timeout in seconds for each http request made"` } @@ -26,25 +22,18 @@ var opts struct { func init() { _, err := flags.Parse(&opts) if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) os.Exit(2) } } func main() { - data, err := ioutil.ReadFile(opts.File) + t, err := tester.NewTest(opts.File) if err != nil { - fmt.Fprintf(os.Stderr, "could not read test file: %v\n", err) - os.Exit(2) - } - - t := tester.Test{} - if err := unmarshal(opts.File, data, &t); err != nil { - fmt.Fprintf(os.Stderr, "could not unmarshal test data: %v\n", err) + fmt.Fprintf(os.Stderr, err.Error()) os.Exit(2) } - prepareResponseBody(&t) - url := opts.URL if opts.Port != 0 { url = fmt.Sprintf("%s:%d", url, opts.Port) @@ -57,40 +46,13 @@ func main() { }, } - testRunner := tester.NewRunner(url, t, + runner := tester.NewRunner(url, t, tester.WithVerboseModeOn(opts.Verbose), tester.WithHTTPClient(client), ) - ok := testRunner.Run() + ok := runner.Run() if !ok { os.Exit(1) } } - -func unmarshal(filename string, in []byte, out interface{}) error { - var unmarshalError error - - ext := strings.Trim(path.Ext(filename), ".") - switch ext { - case "yaml": - fallthrough - case "yml": - unmarshalError = yaml.Unmarshal(in, out) - default: - unmarshalError = json.Unmarshal(in, out) - } - - return unmarshalError -} - -// In order to keep retro compatibility with ExpectedResponseBody, and at the same time introducing multiple response check with ExpectedResponse -func prepareResponseBody(t *tester.Test) { - if t != nil && t.Contracts != nil && len(t.Contracts) > 0 { - for _, c := range t.Contracts { - if c.ExpectedResponseBody != "" { - c.ExpectedResponses = append(c.ExpectedResponses, c.ExpectedResponseBody) - } - } - } -}