-
Notifications
You must be signed in to change notification settings - Fork 0
/
steps.js
78 lines (61 loc) · 1.98 KB
/
steps.js
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
module.exports = function() {
function Steps() {
this.generators = []
this.descriptions = []
}
Steps.prototype.add = function(description, generator) {
this.descriptions.push(description)
this.generators.push(generator)
}
Steps.prototype.play = function(handlers) {
for(var i=0; i<this.generators.length; i++) {
var generator = this.generators[i]
var description = this.descriptions[i]
if (generator) {
var outputs = runGenerator(generator, handlers)
} else {
var outputs = []
}
var stepHandler = handlers.step
if (!stepHandler) {
throw new Error("When you play steps you need a step handler. Try steps.play({step: function(description, results) { console.log(description+\" is done.\")")
}
stepHandler.call(handlers, description, outputs)
}
}
function runGenerator(generator, handlers) {
var names = argNames(generator)
var outputs = []
var args = names.map(toHandler)
generator.apply(null, args)
function toHandler(name) {
var handler = handlers[name]
if (!handler) {
console.log("generator:", generator)
throw new Error("A step generator used a "+name+" command, but you didn't provide a handler for it. Try steps.play({"+name+": function(some, args) { return \"some result\" })")
}
return captureOutput.bind(null, handler, handlers)
}
function captureOutput(handler, handlers) {
var args = Array.prototype.slice.call(arguments, 2)
var output = handler.apply(handlers, args)
if (!output) {
console.log(handler.toString())
throw new Error("no output")
}
outputs.push(output)
return output
}
return outputs
}
function argNames(func) {
var pattern = /^function[ a-zA-Z]*\(([a-zA-Z, ]*)/
var argString = func.toString().match(pattern)[1]
if (argString) {
return argString.split(/, ?/)
} else {
return []
}
}
return Steps
}()