This repository was archived by the owner on Feb 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcreateTestIterator.ts
More file actions
113 lines (110 loc) · 2.88 KB
/
Copy pathcreateTestIterator.ts
File metadata and controls
113 lines (110 loc) · 2.88 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { IIterationListener, IVisitor, IStep, ITestIterator } from './types'
import * as StepName from './StepName'
export default function createTestIterator(
visitor?,
iterationListener?
): ITestIterator {
let test: IStep = { children: [], name: StepName.coerce('(not loaded)') }
let stepper
return {
setTest(_test) {
test = _test
stepper = null
},
getTest() {
return test
},
begin(beginningStep?) {
stepper = createStepper(test, beginningStep, visitor, iterationListener)
},
getCurrentStepNumber() {
if (!stepper) return null
if (stepper.isDone()) return null
return stepper.getCurrentStep().number
},
getCurrentStep() {
if (!stepper) throw new Error('Test not started.')
if (stepper.isDone()) throw new Error('Test already finished.')
return stepper.getCurrentStep()
},
isDone() {
if (!stepper) return false
return stepper.isDone()
},
actionPassed() {
stepper.actionPassed()
},
actionFailed(error) {
stepper.actionFailed(error)
}
}
}
function createStepper(
test,
beginningStep?,
visitor?: Partial<IVisitor>,
iterationListener: Partial<IIterationListener> = {}
) {
function* generateSteps() {
let found = !beginningStep
const deferredSteps: IStep[] = []
yield* walk(test)
for (const step of deferredSteps) {
yield* walk(step)
}
function* walk(node) {
if (!found && node.number === beginningStep) {
found = true
}
if (found && visitor && visitor.visitNode && node.number) {
visitor.visitNode(node)
}
if (iterationListener.onEnter) {
iterationListener.onEnter(node)
}
if (node.action) {
if (found) {
const { ok, error } = yield node
if (iterationListener.onExit) {
iterationListener.onExit(node, error)
}
return ok
} else {
return true
}
} else if (node.children) {
let stillOk = true
for (const child of node.children) {
if (child.defer && stillOk) {
if (visitor && visitor.visitDeferNode && child.number) {
visitor.visitDeferNode(child)
}
deferredSteps.push(child)
} else if (child.cleanup || child.independent || stillOk) {
stillOk = (yield* walk(child)) && stillOk
}
}
if (iterationListener.onExit) {
iterationListener.onExit(node)
}
return stillOk
}
}
}
const iterator = generateSteps()
let currentState = iterator.next()
return {
isDone() {
return currentState.done
},
getCurrentStep() {
return currentState.value
},
actionPassed() {
currentState = iterator.next({ ok: true })
},
actionFailed(error) {
currentState = iterator.next({ ok: false, error })
}
}
}