-
Notifications
You must be signed in to change notification settings - Fork 31
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
fix some missing log informations and add VerifyJSON assert method #15
base: master
Are you sure you want to change the base?
Changes from 1 commit
337d62a
e868868
1992849
e6727ae
6514fb9
71b90ad
61a33f2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,9 @@ import ( | |
"reflect" | ||
) | ||
|
||
// convert types take an int and return a string value. | ||
type FnJsonVerify func(map[string]interface{}) error | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. JSON can be a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see your point, I'm agree, but in this case data come from unmarshalBody which return a map[string]interface{} , we have 2 possibilities:
|
||
|
||
func unmarshal(buf []byte) (map[string]interface{}, error) { | ||
data := make(map[string]interface{}) | ||
if err := json.Unmarshal(buf, &data); err != nil { | ||
|
@@ -23,6 +26,7 @@ func unmarshalBody(res *http.Response) (map[string]interface{}, error) { | |
if err != nil { | ||
return nil, err | ||
} | ||
res.Body = ioutil.NopCloser(bytes.NewBuffer(body)) | ||
if len(body) == 0 { | ||
return nil, nil | ||
} | ||
|
@@ -109,3 +113,17 @@ func JSON(data interface{}) Func { | |
return compare(body, data) | ||
} | ||
} | ||
|
||
// VerifyJSON extract Json in body and call fn with result | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
// write your own test on data | ||
func VerifyJSON(fn FnJsonVerify) Func { | ||
return func(res *http.Response, req *http.Request) error { | ||
// Read and unmarshal response body as JSON | ||
body, err := unmarshalBody(res) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return fn(body) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -155,6 +155,13 @@ func (e *Expect) JSON(data interface{}) *Expect { | |
return e | ||
} | ||
|
||
// VerifyJSON asserts the response body with the given function | ||
// write your own test on data | ||
func (e *Expect) VerifyJSON(fn assert.FnJsonVerify) *Expect { | ||
e.AssertFunc(assert.VerifyJSON(fn)) | ||
return e | ||
} | ||
|
||
// JSONSchema asserts the response body with the given | ||
// JSON schema definition. | ||
func (e *Expect) JSONSchema(schema string) *Expect { | ||
|
@@ -196,7 +203,10 @@ func (e *Expect) Done() error { | |
// Run assertions | ||
err = e.run(res.RawResponse, res.RawRequest) | ||
if err != nil { | ||
e.test.Error(err) | ||
logerrorf(e.test, err.Error()) | ||
//e.test.Error(err) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's remove dead code. |
||
Dump(e.test, res.RawResponse) | ||
|
||
} | ||
|
||
return err | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package baloo | ||
|
||
/// Come from https://github.com/emicklei/forest/ | ||
// LICENSE MIT https://github.com/emicklei/forest/blob/master/LICENSE.txt | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"runtime" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
var scanStackForFile = true | ||
var logf_func = logf | ||
|
||
const noStackOffset = 0 | ||
|
||
// Logf adds the actual file:line information to the log message | ||
func Logf(t *testing.T, format string, args ...interface{}) { | ||
logf_func(t, noStackOffset, "\n"+format, args...) | ||
} | ||
|
||
func logfatal(t *testing.T, format string, args ...interface{}) { | ||
logf_func(t, noStackOffset, format, args...) | ||
t.FailNow() | ||
} | ||
|
||
// Error is equivalent to Log followed by Fail. | ||
func logerror(t *testing.T, args ...interface{}) { | ||
logerrorf(t, "\terror: "+tabify("%s")+"\n", args) | ||
} | ||
|
||
func logerrorf(t *testing.T, format string, args ...interface{}) { | ||
logf_func(t, noStackOffset, format, args...) | ||
t.Fail() | ||
} | ||
|
||
func logf(t *testing.T, stackOffset int, format string, args ...interface{}) { | ||
var file string | ||
var line int | ||
var ok bool | ||
if scanStackForFile { | ||
offset := 0 | ||
outside := false | ||
for !outside { | ||
_, file, line, ok = runtime.Caller(2 + offset) | ||
outside = !strings.Contains(file, "/baloo/") | ||
offset++ | ||
} | ||
} else { | ||
_, file, line, ok = runtime.Caller(2) | ||
} | ||
if ok { | ||
// Truncate file name at last file name separator. | ||
if index := strings.LastIndex(file, "/"); index >= 0 { | ||
file = file[index+1:] | ||
} else if index = strings.LastIndex(file, "\\"); index >= 0 { | ||
file = file[index+1:] | ||
} | ||
} else { | ||
file = "???" | ||
line = 1 | ||
} | ||
t.Logf("<-- %s:%d "+format, append([]interface{}{file, line}, args...)...) | ||
} | ||
|
||
// Dump is a convenient method to log the full contents of a request and its response. | ||
func Dump(t *testing.T, resp *http.Response) { | ||
// dump request | ||
var buffer bytes.Buffer | ||
buffer.WriteString("\n") | ||
buffer.WriteString(fmt.Sprintf("%v %v\n", resp.Request.Method, resp.Request.URL)) | ||
for k, v := range resp.Request.Header { | ||
if len(k) > 0 { | ||
buffer.WriteString(fmt.Sprintf("%s : %v\n", k, strings.Join(v, ","))) | ||
} | ||
} | ||
if resp == nil { | ||
buffer.WriteString("-- no response --") | ||
Logf(t, buffer.String()) | ||
return | ||
} | ||
// dump response | ||
buffer.WriteString(fmt.Sprintf("\n%s\n", resp.Status)) | ||
for k, v := range resp.Header { | ||
if len(k) > 0 { | ||
buffer.WriteString(fmt.Sprintf("%s : %v\n", k, strings.Join(v, ","))) | ||
} | ||
} | ||
if resp.Body != nil { | ||
body, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
if resp.StatusCode/100 == 3 { | ||
// redirect closes body ; nothing to read | ||
buffer.WriteString("\n") | ||
} else { | ||
buffer.WriteString(fmt.Sprintf("unable to read body:%v", err)) | ||
} | ||
} else { | ||
if len(body) > 0 { | ||
buffer.WriteString("\n") | ||
} | ||
buffer.WriteString(string(body)) | ||
} | ||
resp.Body.Close() | ||
// put the body back for re-reads | ||
resp.Body = ioutil.NopCloser(bytes.NewReader(body)) | ||
} | ||
buffer.WriteString("\n") | ||
Logf(t, buffer.String()) | ||
} | ||
|
||
func tabify(format string) string { | ||
if strings.HasPrefix(format, "\n") { | ||
return strings.Replace(format, "\n", "\n\t\t", 1) | ||
} | ||
return format | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We possibly want to run some assertion logic here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean a more complex sample ?
With something like "github.com/mitchellh/mapstructure"
err := mapstructure.Decode(data, destStruct)
?