implements multistep - initial attempt
Этот коммит содержится в:
родитель
88d441e5ce
коммит
ba80ebcd33
2 изменённых файлов: 60 добавлений и 11 удалений
|
@ -53,7 +53,7 @@ func (sd *StepDef) definitionID() string {
|
||||||
|
|
||||||
// run a step with the matched arguments using
|
// run a step with the matched arguments using
|
||||||
// reflect
|
// reflect
|
||||||
func (sd *StepDef) run() error {
|
func (sd *StepDef) run() interface{} {
|
||||||
typ := sd.hv.Type()
|
typ := sd.hv.Type()
|
||||||
if len(sd.args) < typ.NumIn() {
|
if len(sd.args) < typ.NumIn() {
|
||||||
return fmt.Errorf("func expects %d arguments, which is more than %d matched from step", typ.NumIn(), len(sd.args))
|
return fmt.Errorf("func expects %d arguments, which is more than %d matched from step", typ.NumIn(), len(sd.args))
|
||||||
|
@ -171,12 +171,7 @@ func (sd *StepDef) run() error {
|
||||||
return fmt.Errorf("the argument %d type %s is not supported", i, param.Kind())
|
return fmt.Errorf("the argument %d type %s is not supported", i, param.Kind())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret := sd.hv.Call(values)[0].Interface()
|
return sd.hv.Call(values)[0].Interface()
|
||||||
if nil == ret {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret.(error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sd *StepDef) shouldBeString(idx int) (string, error) {
|
func (sd *StepDef) shouldBeString(idx int) (string, error) {
|
||||||
|
|
62
suite.go
62
suite.go
|
@ -95,12 +95,25 @@ func (s *Suite) Step(expr interface{}, stepFunc interface{}) {
|
||||||
if typ.Kind() != reflect.Func {
|
if typ.Kind() != reflect.Func {
|
||||||
panic(fmt.Sprintf("expected handler to be func, but got: %T", stepFunc))
|
panic(fmt.Sprintf("expected handler to be func, but got: %T", stepFunc))
|
||||||
}
|
}
|
||||||
|
|
||||||
if typ.NumOut() != 1 {
|
if typ.NumOut() != 1 {
|
||||||
panic(fmt.Sprintf("expected handler to return an error, but it has more values in return: %d", typ.NumOut()))
|
panic(fmt.Sprintf("expected handler to return only one value, but it has: %d", typ.NumOut()))
|
||||||
}
|
}
|
||||||
if typ.Out(0).Kind() != reflect.Interface || !typ.Out(0).Implements(errorInterface) {
|
|
||||||
panic(fmt.Sprintf("expected handler to return an error interface, but we have: %s", typ.Out(0).Kind()))
|
typ = typ.Out(0)
|
||||||
|
switch typ.Kind() {
|
||||||
|
case reflect.Interface:
|
||||||
|
if !typ.Implements(errorInterface) {
|
||||||
|
panic(fmt.Sprintf("expected handler to return an error, but got: %s", typ.Kind()))
|
||||||
|
}
|
||||||
|
case reflect.Slice:
|
||||||
|
if typ.Elem().Kind() != reflect.String {
|
||||||
|
panic(fmt.Sprintf("expected handler to return []string for multistep, but got: []%s", typ.Kind()))
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("expected handler to return an error or []string, but got: %s", typ.Kind()))
|
||||||
}
|
}
|
||||||
|
|
||||||
s.steps = append(s.steps, &StepDef{
|
s.steps = append(s.steps, &StepDef{
|
||||||
Handler: stepFunc,
|
Handler: stepFunc,
|
||||||
Expr: regex,
|
Expr: regex,
|
||||||
|
@ -241,10 +254,51 @@ func (s *Suite) runStep(step *gherkin.Step, prevStepErr error) (err error) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = match.run()
|
err = s.maybeSubSteps(match.run())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Suite) maybeSubSteps(result interface{}) error {
|
||||||
|
if nil == result {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err, ok := result.(error); ok {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
steps, ok := result.([]string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected error, should have been []string: %T - %+v", result, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, step := range steps {
|
||||||
|
var def *StepDef
|
||||||
|
for _, h := range s.steps {
|
||||||
|
if m := h.Expr.FindStringSubmatch(step); len(m) > 0 {
|
||||||
|
var args []interface{}
|
||||||
|
for _, m := range m[1:] {
|
||||||
|
args = append(args, m)
|
||||||
|
}
|
||||||
|
h.args = args
|
||||||
|
def = h
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if def == nil {
|
||||||
|
return ErrUndefined
|
||||||
|
}
|
||||||
|
|
||||||
|
// @TODO: step hooks only take gherkin.Step
|
||||||
|
// @TODO: cannot call formatter to register step execution either
|
||||||
|
if err := s.maybeSubSteps(def.run()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Suite) runSteps(steps []*gherkin.Step, prevErr error) (err error) {
|
func (s *Suite) runSteps(steps []*gherkin.Step, prevErr error) (err error) {
|
||||||
err = prevErr
|
err = prevErr
|
||||||
for _, step := range steps {
|
for _, step := range steps {
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче