@@ -22,16 +22,68 @@ import (
2222 unstructured "github.com/linuxsuren/unstructured/pkg"
2323)
2424
25+ // LevelWriter represents a writer with level
26+ type LevelWriter interface {
27+ Info (format string , a ... any )
28+ Debug (format string , a ... any )
29+ }
30+
31+ // FormatPrinter represents a formart printer with level
32+ type FormatPrinter interface {
33+ Fprintf (w io.Writer , level , format string , a ... any ) (n int , err error )
34+ }
35+
36+ type defaultLevelWriter struct {
37+ level int
38+ io.Writer
39+ FormatPrinter
40+ }
41+
42+ // NewDefaultLevelWriter creates a default LevelWriter instance
43+ func NewDefaultLevelWriter (level string , writer io.Writer ) LevelWriter {
44+ result := & defaultLevelWriter {
45+ Writer : writer ,
46+ }
47+ switch level {
48+ case "debug" :
49+ result .level = 7
50+ case "info" :
51+ result .level = 3
52+ }
53+ return result
54+ }
55+
56+ // Fprintf implements interface FormatPrinter
57+ func (w * defaultLevelWriter ) Fprintf (writer io.Writer , level int , format string , a ... any ) (n int , err error ) {
58+ if level <= w .level {
59+ return fmt .Fprintf (writer , format , a ... )
60+ }
61+ return
62+ }
63+
64+ // Info writes the info level message
65+ func (w * defaultLevelWriter ) Info (format string , a ... any ) {
66+ w .Fprintf (w .Writer , 3 , format , a ... )
67+ }
68+
69+ // Debug writes the debug level message
70+ func (w * defaultLevelWriter ) Debug (format string , a ... any ) {
71+ w .Fprintf (w .Writer , 7 , format , a ... )
72+ }
73+
74+ // TestCaseRunner represents a test case runner
2575type TestCaseRunner interface {
2676 RunTestCase (testcase * testing.TestCase , dataContext interface {}, ctx context.Context ) (output interface {}, err error )
2777 WithOutputWriter (io.Writer ) TestCaseRunner
78+ WithWriteLevel (level string ) TestCaseRunner
2879 WithTestReporter (TestReporter ) TestCaseRunner
2980}
3081
3182// ReportRecord represents the raw data of a HTTP request
3283type ReportRecord struct {
3384 Method string
3485 API string
86+ Body string
3587 BeginTime time.Time
3688 EndTime time.Time
3789 Error error
@@ -103,17 +155,20 @@ type TestReporter interface {
103155type simpleTestCaseRunner struct {
104156 testReporter TestReporter
105157 writer io.Writer
158+ log LevelWriter
106159}
107160
108161// NewSimpleTestCaseRunner creates the instance of the simple test case runner
109162func NewSimpleTestCaseRunner () TestCaseRunner {
110163 runner := & simpleTestCaseRunner {}
111- return runner .WithOutputWriter (io .Discard ).WithTestReporter (NewDiscardTestReporter ())
164+ return runner .WithOutputWriter (io .Discard ).
165+ WithWriteLevel ("info" ).
166+ WithTestReporter (NewDiscardTestReporter ())
112167}
113168
114169// RunTestCase is the main entry point of a test case
115170func (r * simpleTestCaseRunner ) RunTestCase (testcase * testing.TestCase , dataContext interface {}, ctx context.Context ) (output interface {}, err error ) {
116- fmt . Fprintf ( r . writer , "start to run: '%s'\n " , testcase .Name )
171+ r . log . Info ( "start to run: '%s'\n " , testcase .Name )
117172 record := NewReportRecord ()
118173 defer func (rr * ReportRecord ) {
119174 rr .EndTime = time .Now ()
@@ -182,7 +237,7 @@ func (r *simpleTestCaseRunner) RunTestCase(testcase *testing.TestCase, dataConte
182237 request .Header .Add (key , val )
183238 }
184239
185- fmt . Fprintf ( r . writer , "start to send request to %s\n " , testcase .Request .API )
240+ r . log . Info ( "start to send request to %s\n " , testcase .Request .API )
186241
187242 // send the HTTP request
188243 var resp * http.Response
@@ -194,6 +249,8 @@ func (r *simpleTestCaseRunner) RunTestCase(testcase *testing.TestCase, dataConte
194249 if responseBodyData , err = io .ReadAll (resp .Body ); err != nil {
195250 return
196251 }
252+ record .Body = string (responseBodyData )
253+ r .log .Debug ("response body: %s\n " , record .Body )
197254
198255 if err = testcase .Expect .Render (nil ); err != nil {
199256 return
@@ -218,6 +275,7 @@ func (r *simpleTestCaseRunner) RunTestCase(testcase *testing.TestCase, dataConte
218275 }
219276 }
220277
278+ var bodyMap map [string ]interface {}
221279 mapOutput := map [string ]interface {}{}
222280 if err = json .Unmarshal (responseBodyData , & mapOutput ); err != nil {
223281 switch b := err .(type ) {
@@ -231,17 +289,22 @@ func (r *simpleTestCaseRunner) RunTestCase(testcase *testing.TestCase, dataConte
231289 return
232290 }
233291 output = arrayOutput
292+ mapOutput ["data" ] = arrayOutput
234293 default :
235294 return
236295 }
237296 } else {
297+ bodyMap = mapOutput
238298 output = mapOutput
299+ mapOutput = map [string ]interface {}{
300+ "data" : bodyMap ,
301+ }
239302 }
240303
241304 for key , expectVal := range testcase .Expect .BodyFieldsExpect {
242305 var val interface {}
243306 var ok bool
244- if val , ok , err = unstructured .NestedField (mapOutput , strings .Split (key , "/" )... ); err != nil {
307+ if val , ok , err = unstructured .NestedField (bodyMap , strings .Split (key , "/" )... ); err != nil {
245308 err = fmt .Errorf ("failed to get field: %s, %v" , key , err )
246309 return
247310 } else if ! ok {
@@ -260,12 +323,12 @@ func (r *simpleTestCaseRunner) RunTestCase(testcase *testing.TestCase, dataConte
260323
261324 for _ , verify := range testcase .Expect .Verify {
262325 var program * vm.Program
263- if program , err = expr .Compile (verify , expr .Env (output ), expr .AsBool ()); err != nil {
326+ if program , err = expr .Compile (verify , expr .Env (mapOutput ), expr .AsBool ()); err != nil {
264327 return
265328 }
266329
267330 var result interface {}
268- if result , err = expr .Run (program , output ); err != nil {
331+ if result , err = expr .Run (program , mapOutput ); err != nil {
269332 return
270333 }
271334
@@ -283,6 +346,14 @@ func (r *simpleTestCaseRunner) WithOutputWriter(writer io.Writer) TestCaseRunner
283346 return r
284347}
285348
349+ // WithWriteLevel sets the level writer
350+ func (r * simpleTestCaseRunner ) WithWriteLevel (level string ) TestCaseRunner {
351+ if level != "" {
352+ r .log = NewDefaultLevelWriter (level , r .writer )
353+ }
354+ return r
355+ }
356+
286357// WithTestReporter sets the TestReporter
287358func (r * simpleTestCaseRunner ) WithTestReporter (reporter TestReporter ) TestCaseRunner {
288359 r .testReporter = reporter
0 commit comments