From a301266227c18e4885e6dddc6097c468cc4aab64 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Wed, 8 Dec 2021 13:20:23 +0800 Subject: [PATCH] refactor: NewStep --- convert.go | 8 +-- extract.go | 16 +++--- models.go | 5 +- runner.go | 6 +- step.go | 159 +++++++++++++++++++++++++++------------------------- validate.go | 18 +++--- 6 files changed, 110 insertions(+), 102 deletions(-) diff --git a/convert.go b/convert.go index 94eb0b6..263e61b 100644 --- a/convert.go +++ b/convert.go @@ -109,19 +109,19 @@ func (tc *TCase) ToTestCase() (*TestCase, error) { } for _, step := range tc.TestSteps { if step.Request != nil { - testCase.TestSteps = append(testCase.TestSteps, &stepRequestWithOptionalArgs{ + testCase.TestSteps = append(testCase.TestSteps, &StepRequestWithOptionalArgs{ step: step, }) } else if step.TestCase != nil { - testCase.TestSteps = append(testCase.TestSteps, &stepTestCaseWithOptionalArgs{ + testCase.TestSteps = append(testCase.TestSteps, &StepTestCaseWithOptionalArgs{ step: step, }) } else if step.Transaction != nil { - testCase.TestSteps = append(testCase.TestSteps, &stepTransaction{ + testCase.TestSteps = append(testCase.TestSteps, &StepTransaction{ step: step, }) } else if step.Rendezvous != nil { - testCase.TestSteps = append(testCase.TestSteps, &stepRendezvous{ + testCase.TestSteps = append(testCase.TestSteps, &StepRendezvous{ step: step, }) } else { diff --git a/extract.go b/extract.go index 0d0fb38..b426993 100644 --- a/extract.go +++ b/extract.go @@ -2,32 +2,32 @@ package hrp import "fmt" -// implements IStep interface -type stepRequestExtraction struct { +// StepRequestExtraction implements IStep interface. +type StepRequestExtraction struct { step *TStep } // WithJmesPath sets the JMESPath expression to extract from the response. -func (s *stepRequestExtraction) WithJmesPath(jmesPath string, varName string) *stepRequestExtraction { +func (s *StepRequestExtraction) WithJmesPath(jmesPath string, varName string) *StepRequestExtraction { s.step.Extract[varName] = jmesPath return s } // Validate switches to step validation. -func (s *stepRequestExtraction) Validate() *stepRequestValidation { - return &stepRequestValidation{ +func (s *StepRequestExtraction) Validate() *StepRequestValidation { + return &StepRequestValidation{ step: s.step, } } -func (s *stepRequestExtraction) Name() string { +func (s *StepRequestExtraction) Name() string { return s.step.Name } -func (s *stepRequestExtraction) Type() string { +func (s *StepRequestExtraction) Type() string { return fmt.Sprintf("request-%v", s.step.Request.Method) } -func (s *stepRequestExtraction) ToStruct() *TStep { +func (s *StepRequestExtraction) ToStruct() *TStep { return s.step } diff --git a/models.go b/models.go index 5b1306d..aaa2d71 100644 --- a/models.go +++ b/models.go @@ -97,8 +97,8 @@ type ITestCase interface { ToTCase() (*TCase, error) } -// TestCase is a container for one testcase. -// used for testcase runner +// TestCase is a container for one testcase, which is used for testcase runner. +// TestCase implements ITestCase interface. type TestCase struct { Config IConfig TestSteps []IStep @@ -108,6 +108,7 @@ func (tc *TestCase) ToTestCase() (*TestCase, error) { return tc, nil } +// TestCasePath implements ITestCase interface. type TestCasePath struct { Path string } diff --git a/runner.go b/runner.go index 9812a80..6da6228 100644 --- a/runner.go +++ b/runner.go @@ -119,14 +119,14 @@ func (r *hrpRunner) runCase(testcase *TestCase) error { func (r *hrpRunner) runStep(step IStep, config IConfig) (stepResult *stepData, err error) { // step type priority order: transaction > rendezvous > testcase > request - if stepTran, ok := step.(*stepTransaction); ok { + if stepTran, ok := step.(*StepTransaction); ok { // transaction log.Info(). Str("name", stepTran.step.Transaction.Name). Str("type", stepTran.step.Transaction.Type). Msg("transaction") return nil, nil - } else if stepRend, ok := step.(*stepRendezvous); ok { + } else if stepRend, ok := step.(*StepRendezvous); ok { // rendezvous log.Info(). Str("name", stepRend.step.Rendezvous.Name). @@ -162,7 +162,7 @@ func (r *hrpRunner) runStep(step IStep, config IConfig) (stepResult *stepData, e } copiedStep.Variables = parsedVariables // avoid data racing - if _, ok := step.(*stepTestCaseWithOptionalArgs); ok { + if _, ok := step.(*StepTestCaseWithOptionalArgs); ok { // run referenced testcase log.Info().Str("testcase", copiedStep.Name).Msg("run referenced testcase") // TODO: override testcase config diff --git a/step.go b/step.go index 82b29da..5cbc296 100644 --- a/step.go +++ b/step.go @@ -12,6 +12,7 @@ func NewConfig(name string) *Config { } } +// Config implements IConfig interface. type Config struct { cfg *TConfig } @@ -63,273 +64,279 @@ func (c *Config) ToStruct() *TConfig { } // NewStep returns a new constructed teststep with specified step name. -func NewStep(name string) *TStep { - return &TStep{ - Name: name, - Variables: make(map[string]interface{}), +func NewStep(name string) *StepRequest { + return &StepRequest{ + step: &TStep{ + Name: name, + Variables: make(map[string]interface{}), + }, } } +type StepRequest struct { + step *TStep +} + // WithVariables sets variables for current teststep. -func (s *TStep) WithVariables(variables map[string]interface{}) *TStep { - s.Variables = variables +func (s *StepRequest) WithVariables(variables map[string]interface{}) *StepRequest { + s.step.Variables = variables return s } // SetupHook adds a setup hook for current teststep. -func (s *TStep) SetupHook(hook string) *TStep { - s.SetupHooks = append(s.SetupHooks, hook) +func (s *StepRequest) SetupHook(hook string) *StepRequest { + s.step.SetupHooks = append(s.step.SetupHooks, hook) return s } // GET makes a HTTP GET request. -func (s *TStep) GET(url string) *stepRequestWithOptionalArgs { - s.Request = &Request{ +func (s *StepRequest) GET(url string) *StepRequestWithOptionalArgs { + s.step.Request = &Request{ Method: httpGET, URL: url, } - return &stepRequestWithOptionalArgs{ - step: s, + return &StepRequestWithOptionalArgs{ + step: s.step, } } // HEAD makes a HTTP HEAD request. -func (s *TStep) HEAD(url string) *stepRequestWithOptionalArgs { - s.Request = &Request{ +func (s *StepRequest) HEAD(url string) *StepRequestWithOptionalArgs { + s.step.Request = &Request{ Method: httpHEAD, URL: url, } - return &stepRequestWithOptionalArgs{ - step: s, + return &StepRequestWithOptionalArgs{ + step: s.step, } } // POST makes a HTTP POST request. -func (s *TStep) POST(url string) *stepRequestWithOptionalArgs { - s.Request = &Request{ +func (s *StepRequest) POST(url string) *StepRequestWithOptionalArgs { + s.step.Request = &Request{ Method: httpPOST, URL: url, } - return &stepRequestWithOptionalArgs{ - step: s, + return &StepRequestWithOptionalArgs{ + step: s.step, } } // PUT makes a HTTP PUT request. -func (s *TStep) PUT(url string) *stepRequestWithOptionalArgs { - s.Request = &Request{ +func (s *StepRequest) PUT(url string) *StepRequestWithOptionalArgs { + s.step.Request = &Request{ Method: httpPUT, URL: url, } - return &stepRequestWithOptionalArgs{ - step: s, + return &StepRequestWithOptionalArgs{ + step: s.step, } } // DELETE makes a HTTP DELETE request. -func (s *TStep) DELETE(url string) *stepRequestWithOptionalArgs { - s.Request = &Request{ +func (s *StepRequest) DELETE(url string) *StepRequestWithOptionalArgs { + s.step.Request = &Request{ Method: httpDELETE, URL: url, } - return &stepRequestWithOptionalArgs{ - step: s, + return &StepRequestWithOptionalArgs{ + step: s.step, } } // OPTIONS makes a HTTP OPTIONS request. -func (s *TStep) OPTIONS(url string) *stepRequestWithOptionalArgs { - s.Request = &Request{ +func (s *StepRequest) OPTIONS(url string) *StepRequestWithOptionalArgs { + s.step.Request = &Request{ Method: httpOPTIONS, URL: url, } - return &stepRequestWithOptionalArgs{ - step: s, + return &StepRequestWithOptionalArgs{ + step: s.step, } } // PATCH makes a HTTP PATCH request. -func (s *TStep) PATCH(url string) *stepRequestWithOptionalArgs { - s.Request = &Request{ +func (s *StepRequest) PATCH(url string) *StepRequestWithOptionalArgs { + s.step.Request = &Request{ Method: httpPATCH, URL: url, } - return &stepRequestWithOptionalArgs{ - step: s, + return &StepRequestWithOptionalArgs{ + step: s.step, } } // CallRefCase calls a referenced testcase. -func (s *TStep) CallRefCase(tc *TestCase) *stepTestCaseWithOptionalArgs { - s.TestCase = tc - return &stepTestCaseWithOptionalArgs{ - step: s, +func (s *StepRequest) CallRefCase(tc *TestCase) *StepTestCaseWithOptionalArgs { + s.step.TestCase = tc + return &StepTestCaseWithOptionalArgs{ + step: s.step, } } -// implements IStep interface -type stepRequestWithOptionalArgs struct { +// StepRequestWithOptionalArgs implements IStep interface. +type StepRequestWithOptionalArgs struct { step *TStep } // SetVerify sets whether to verify SSL for current HTTP request. -func (s *stepRequestWithOptionalArgs) SetVerify(verify bool) *stepRequestWithOptionalArgs { +func (s *StepRequestWithOptionalArgs) SetVerify(verify bool) *StepRequestWithOptionalArgs { s.step.Request.Verify = verify return s } // SetTimeout sets timeout for current HTTP request. -func (s *stepRequestWithOptionalArgs) SetTimeout(timeout float32) *stepRequestWithOptionalArgs { +func (s *StepRequestWithOptionalArgs) SetTimeout(timeout float32) *StepRequestWithOptionalArgs { s.step.Request.Timeout = timeout return s } // SetProxies sets proxies for current HTTP request. -func (s *stepRequestWithOptionalArgs) SetProxies(proxies map[string]string) *stepRequestWithOptionalArgs { +func (s *StepRequestWithOptionalArgs) SetProxies(proxies map[string]string) *StepRequestWithOptionalArgs { // TODO return s } // SetAllowRedirects sets whether to allow redirects for current HTTP request. -func (s *stepRequestWithOptionalArgs) SetAllowRedirects(allowRedirects bool) *stepRequestWithOptionalArgs { +func (s *StepRequestWithOptionalArgs) SetAllowRedirects(allowRedirects bool) *StepRequestWithOptionalArgs { s.step.Request.AllowRedirects = allowRedirects return s } // SetAuth sets auth for current HTTP request. -func (s *stepRequestWithOptionalArgs) SetAuth(auth map[string]string) *stepRequestWithOptionalArgs { +func (s *StepRequestWithOptionalArgs) SetAuth(auth map[string]string) *StepRequestWithOptionalArgs { // TODO return s } // WithParams sets HTTP request params for current step. -func (s *stepRequestWithOptionalArgs) WithParams(params map[string]interface{}) *stepRequestWithOptionalArgs { +func (s *StepRequestWithOptionalArgs) WithParams(params map[string]interface{}) *StepRequestWithOptionalArgs { s.step.Request.Params = params return s } // WithHeaders sets HTTP request headers for current step. -func (s *stepRequestWithOptionalArgs) WithHeaders(headers map[string]string) *stepRequestWithOptionalArgs { +func (s *StepRequestWithOptionalArgs) WithHeaders(headers map[string]string) *StepRequestWithOptionalArgs { s.step.Request.Headers = headers return s } // WithCookies sets HTTP request cookies for current step. -func (s *stepRequestWithOptionalArgs) WithCookies(cookies map[string]string) *stepRequestWithOptionalArgs { +func (s *StepRequestWithOptionalArgs) WithCookies(cookies map[string]string) *StepRequestWithOptionalArgs { s.step.Request.Cookies = cookies return s } // WithBody sets HTTP request body for current step. -func (s *stepRequestWithOptionalArgs) WithBody(body interface{}) *stepRequestWithOptionalArgs { +func (s *StepRequestWithOptionalArgs) WithBody(body interface{}) *StepRequestWithOptionalArgs { s.step.Request.Body = body return s } // TeardownHook adds a teardown hook for current teststep. -func (s *stepRequestWithOptionalArgs) TeardownHook(hook string) *stepRequestWithOptionalArgs { +func (s *StepRequestWithOptionalArgs) TeardownHook(hook string) *StepRequestWithOptionalArgs { s.step.TeardownHooks = append(s.step.TeardownHooks, hook) return s } // Validate switches to step validation. -func (s *stepRequestWithOptionalArgs) Validate() *stepRequestValidation { - return &stepRequestValidation{ +func (s *StepRequestWithOptionalArgs) Validate() *StepRequestValidation { + return &StepRequestValidation{ step: s.step, } } // Extract switches to step extraction. -func (s *stepRequestWithOptionalArgs) Extract() *stepRequestExtraction { +func (s *StepRequestWithOptionalArgs) Extract() *StepRequestExtraction { s.step.Extract = make(map[string]string) - return &stepRequestExtraction{ + return &StepRequestExtraction{ step: s.step, } } -func (s *stepRequestWithOptionalArgs) Name() string { +func (s *StepRequestWithOptionalArgs) Name() string { if s.step.Name != "" { return s.step.Name } return fmt.Sprintf("%s %s", s.step.Request.Method, s.step.Request.URL) } -func (s *stepRequestWithOptionalArgs) Type() string { +func (s *StepRequestWithOptionalArgs) Type() string { return fmt.Sprintf("request-%v", s.step.Request.Method) } -func (s *stepRequestWithOptionalArgs) ToStruct() *TStep { +func (s *StepRequestWithOptionalArgs) ToStruct() *TStep { return s.step } -// implements IStep interface -type stepTestCaseWithOptionalArgs struct { +// StepTestCaseWithOptionalArgs implements IStep interface. +type StepTestCaseWithOptionalArgs struct { step *TStep } // TeardownHook adds a teardown hook for current teststep. -func (s *stepTestCaseWithOptionalArgs) TeardownHook(hook string) *stepTestCaseWithOptionalArgs { +func (s *StepTestCaseWithOptionalArgs) TeardownHook(hook string) *StepTestCaseWithOptionalArgs { s.step.TeardownHooks = append(s.step.TeardownHooks, hook) return s } // Export specifies variable names to export from referenced testcase for current step. -func (s *stepTestCaseWithOptionalArgs) Export(names ...string) *stepTestCaseWithOptionalArgs { +func (s *StepTestCaseWithOptionalArgs) Export(names ...string) *StepTestCaseWithOptionalArgs { s.step.Export = append(s.step.Export, names...) return s } -func (s *stepTestCaseWithOptionalArgs) Name() string { +func (s *StepTestCaseWithOptionalArgs) Name() string { if s.step.Name != "" { return s.step.Name } return s.step.TestCase.Config.Name() } -func (s *stepTestCaseWithOptionalArgs) Type() string { +func (s *StepTestCaseWithOptionalArgs) Type() string { return "testcase" } -func (s *stepTestCaseWithOptionalArgs) ToStruct() *TStep { +func (s *StepTestCaseWithOptionalArgs) ToStruct() *TStep { return s.step } -// implements IStep interface -type stepTransaction struct { +// StepTransaction implements IStep interface. +type StepTransaction struct { step *TStep } -func (s *stepTransaction) Name() string { +func (s *StepTransaction) Name() string { if s.step.Name != "" { return s.step.Name } return fmt.Sprintf("transaction %s %s", s.step.Transaction.Name, s.step.Transaction.Type) } -func (s *stepTransaction) Type() string { +func (s *StepTransaction) Type() string { return "transaction" } -func (s *stepTransaction) ToStruct() *TStep { +func (s *StepTransaction) ToStruct() *TStep { return s.step } -// implements IStep interface -type stepRendezvous struct { +// StepRendezvous implements IStep interface. +type StepRendezvous struct { step *TStep } -func (s *stepRendezvous) Name() string { +func (s *StepRendezvous) Name() string { if s.step.Name != "" { return s.step.Name } return s.step.Rendezvous.Name } -func (s *stepRendezvous) Type() string { +func (s *StepRendezvous) Type() string { return "rendezvous" } -func (s *stepRendezvous) ToStruct() *TStep { +func (s *StepRendezvous) ToStruct() *TStep { return s.step } diff --git a/validate.go b/validate.go index e522ac9..f5d67a8 100644 --- a/validate.go +++ b/validate.go @@ -4,27 +4,27 @@ import ( "fmt" ) -// implements IStep interface -type stepRequestValidation struct { +// StepRequestValidation implements IStep interface. +type StepRequestValidation struct { step *TStep } -func (s *stepRequestValidation) Name() string { +func (s *StepRequestValidation) Name() string { if s.step.Name != "" { return s.step.Name } return fmt.Sprintf("%s %s", s.step.Request.Method, s.step.Request.URL) } -func (s *stepRequestValidation) Type() string { +func (s *StepRequestValidation) Type() string { return fmt.Sprintf("request-%v", s.step.Request.Method) } -func (s *stepRequestValidation) ToStruct() *TStep { +func (s *StepRequestValidation) ToStruct() *TStep { return s.step } -func (s *stepRequestValidation) AssertEqual(jmesPath string, expected interface{}, msg string) *stepRequestValidation { +func (s *StepRequestValidation) AssertEqual(jmesPath string, expected interface{}, msg string) *StepRequestValidation { v := Validator{ Check: jmesPath, Assert: "equals", @@ -35,7 +35,7 @@ func (s *stepRequestValidation) AssertEqual(jmesPath string, expected interface{ return s } -func (s *stepRequestValidation) AssertStartsWith(jmesPath string, expected interface{}, msg string) *stepRequestValidation { +func (s *StepRequestValidation) AssertStartsWith(jmesPath string, expected interface{}, msg string) *StepRequestValidation { v := Validator{ Check: jmesPath, Assert: "startswith", @@ -46,7 +46,7 @@ func (s *stepRequestValidation) AssertStartsWith(jmesPath string, expected inter return s } -func (s *stepRequestValidation) AssertEndsWith(jmesPath string, expected interface{}, msg string) *stepRequestValidation { +func (s *StepRequestValidation) AssertEndsWith(jmesPath string, expected interface{}, msg string) *StepRequestValidation { v := Validator{ Check: jmesPath, Assert: "endswith", @@ -57,7 +57,7 @@ func (s *stepRequestValidation) AssertEndsWith(jmesPath string, expected interfa return s } -func (s *stepRequestValidation) AssertLengthEqual(jmesPath string, expected interface{}, msg string) *stepRequestValidation { +func (s *StepRequestValidation) AssertLengthEqual(jmesPath string, expected interface{}, msg string) *StepRequestValidation { v := Validator{ Check: jmesPath, Assert: "length_equals",