-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsteps.go
92 lines (77 loc) · 1.9 KB
/
steps.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package gourd
import (
"fmt"
)
type step_result int
const (
success step_result = iota
pending
fail
)
type steps interface {
begin_scenario()
matching_step(step string) (string, bool, []capturing_group)
add_step(pattern string) Step
invoke_step(id string, arguments []string) (step_result, string)
}
type capturing_group struct {
value string
position uint
}
type gourd_steps struct {
new_context func() interface{}
context interface{}
steps map[string]*gourd_step
id int
}
func (steps *gourd_steps) begin_scenario() {
if steps.new_context != nil {
steps.context = steps.new_context()
}
}
func (steps *gourd_steps) matching_step(pattern string) (string, bool, []capturing_group) {
for id, step := range steps.steps {
if step.regex.MatchString(pattern) {
arguments := []capturing_group{}
submatches := step.regex.FindStringSubmatch(pattern)
positions := step.regex.FindStringSubmatchIndex(pattern)
for i, submatch := range submatches {
if i > 0 {
position := uint(positions[2*i])
arguments = append(arguments, capturing_group{value: submatch, position: position})
}
}
return id, true, arguments
}
}
return "", false, []capturing_group{}
}
func (steps *gourd_steps) add_step(pattern string) Step {
if steps.steps == nil {
steps.steps = make(map[string]*gourd_step)
}
step := new_step(pattern)
steps.steps[steps.nextId()] = step
return step
}
func (steps *gourd_steps) invoke_step(id string, arguments []string) (result step_result, message string) {
step, ok := steps.steps[id]
if !ok {
return fail, ""
}
if step.action == nil {
return pending, ""
}
defer func() {
if err := recover(); err != nil {
result = fail
message = fmt.Sprintf("%v", err)
}
}()
step.action(steps.context, &gourd_arguments{arguments})
return success, ""
}
func (steps *gourd_steps) nextId() string {
steps.id++
return fmt.Sprintf("%d", steps.id)
}