mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-11 18:11:21 +08:00
refactor: move hrp/ to root folder
This commit is contained in:
139
step_api.go
Normal file
139
step_api.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package hrp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// IAPI represents interface for api,
|
||||
// includes API and APIPath.
|
||||
type IAPI interface {
|
||||
GetPath() string
|
||||
ToAPI() (*API, error)
|
||||
}
|
||||
|
||||
type API struct {
|
||||
Name string `json:"name" yaml:"name"` // required
|
||||
Request *Request `json:"request,omitempty" yaml:"request,omitempty"`
|
||||
Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"`
|
||||
SetupHooks []string `json:"setup_hooks,omitempty" yaml:"setup_hooks,omitempty"`
|
||||
TeardownHooks []string `json:"teardown_hooks,omitempty" yaml:"teardown_hooks,omitempty"`
|
||||
Extract map[string]string `json:"extract,omitempty" yaml:"extract,omitempty"`
|
||||
Validators []interface{} `json:"validate,omitempty" yaml:"validate,omitempty"`
|
||||
Export []string `json:"export,omitempty" yaml:"export,omitempty"`
|
||||
Path string
|
||||
}
|
||||
|
||||
func (api *API) GetPath() string {
|
||||
return api.Path
|
||||
}
|
||||
|
||||
func (api *API) ToAPI() (*API, error) {
|
||||
return api, nil
|
||||
}
|
||||
|
||||
// APIPath implements IAPI interface.
|
||||
type APIPath string
|
||||
|
||||
func (path *APIPath) GetPath() string {
|
||||
return fmt.Sprintf("%v", *path)
|
||||
}
|
||||
|
||||
func (path *APIPath) ToAPI() (*API, error) {
|
||||
api := &API{}
|
||||
apiPath := path.GetPath()
|
||||
err := LoadFileObject(apiPath, api)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 1. deal with request body compatibility
|
||||
convertCompatRequestBody(api.Request)
|
||||
// 2. deal with validators compatibility
|
||||
err = convertCompatValidator(api.Validators)
|
||||
// 3. deal with extract expr including hyphen
|
||||
convertExtract(api.Extract)
|
||||
return api, err
|
||||
}
|
||||
|
||||
// StepAPIWithOptionalArgs implements IStep interface.
|
||||
type StepAPIWithOptionalArgs struct {
|
||||
StepConfig
|
||||
API interface{} `json:"api,omitempty" yaml:"api,omitempty"` // *APIPath or *API
|
||||
}
|
||||
|
||||
// TeardownHook adds a teardown hook for current teststep.
|
||||
func (s *StepAPIWithOptionalArgs) TeardownHook(hook string) *StepAPIWithOptionalArgs {
|
||||
s.TeardownHooks = append(s.TeardownHooks, hook)
|
||||
return s
|
||||
}
|
||||
|
||||
// Export specifies variable names to export from referenced api for current step.
|
||||
func (s *StepAPIWithOptionalArgs) Export(names ...string) *StepAPIWithOptionalArgs {
|
||||
api, ok := s.API.(*API)
|
||||
if ok {
|
||||
s.StepExport = append(api.Export, names...)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *StepAPIWithOptionalArgs) Name() string {
|
||||
if s.StepName != "" {
|
||||
return s.StepName
|
||||
}
|
||||
api, ok := s.API.(*API)
|
||||
if ok {
|
||||
return api.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *StepAPIWithOptionalArgs) Type() StepType {
|
||||
return StepTypeAPI
|
||||
}
|
||||
|
||||
func (s *StepAPIWithOptionalArgs) Config() *StepConfig {
|
||||
return &s.StepConfig
|
||||
}
|
||||
|
||||
func (s *StepAPIWithOptionalArgs) Run(r *SessionRunner) (stepResult *StepResult, err error) {
|
||||
defer func() {
|
||||
stepResult.StepType = StepTypeAPI
|
||||
}()
|
||||
// extend request with referenced API
|
||||
api, _ := s.API.(*API)
|
||||
step := &StepRequestWithOptionalArgs{}
|
||||
// deep copy step to avoid data racing
|
||||
if err = copier.Copy(step, s.StepConfig); err != nil {
|
||||
log.Error().Err(err).Msg("copy step failed")
|
||||
return
|
||||
}
|
||||
extendWithAPI(step, api)
|
||||
stepResult, err = runStepRequest(r, step)
|
||||
return
|
||||
}
|
||||
|
||||
// extend teststep with api, teststep will merge and override referenced api
|
||||
func extendWithAPI(testStep *StepRequestWithOptionalArgs, overriddenStep *API) {
|
||||
// override api name
|
||||
if testStep.StepName == "" {
|
||||
testStep.StepName = overriddenStep.Name
|
||||
}
|
||||
// merge & override request
|
||||
testStep.Request = overriddenStep.Request
|
||||
// init upload
|
||||
if len(testStep.Request.Upload) != 0 {
|
||||
initUpload(testStep)
|
||||
}
|
||||
// merge & override variables
|
||||
testStep.Variables = mergeVariables(testStep.Variables, overriddenStep.Variables)
|
||||
// merge & override extractors
|
||||
testStep.StepConfig.Extract = mergeMap(testStep.StepConfig.Extract, overriddenStep.Extract)
|
||||
// merge & override validators
|
||||
testStep.Validators = mergeValidators(testStep.Validators, overriddenStep.Validators)
|
||||
// merge & override setupHooks
|
||||
testStep.SetupHooks = mergeSlices(testStep.SetupHooks, overriddenStep.SetupHooks)
|
||||
// merge & override teardownHooks
|
||||
testStep.TeardownHooks = mergeSlices(testStep.TeardownHooks, overriddenStep.TeardownHooks)
|
||||
}
|
||||
Reference in New Issue
Block a user