1
|
|
|
var Yaml = require('js-yaml') |
2
|
|
|
|
3
|
|
|
var Objects = require('../Utility').Objects |
4
|
|
|
var Factory = require('./Factory').Factory |
5
|
|
|
|
6
|
|
|
var definition = { |
7
|
|
|
defaults: { |
8
|
|
|
allure: { |
9
|
|
|
events: { |
10
|
|
|
filename: 'voxengine.events.yml', |
11
|
|
|
mimeType: 'application/x-yaml' |
12
|
|
|
}, |
13
|
|
|
listeners: { |
14
|
|
|
filename: 'voxengine.event-listeners.yml', |
15
|
|
|
mimeType: 'application/x-yaml' |
16
|
|
|
}, |
17
|
|
|
customData: { |
18
|
|
|
filename: 'voxengine.custom-data.yml', |
19
|
|
|
mimeType: 'application/x-yaml' |
20
|
|
|
} |
21
|
|
|
}, |
22
|
|
|
customData: { |
23
|
|
|
default: '' |
24
|
|
|
}, |
25
|
|
|
terminate: { |
26
|
|
|
throwOnMultipleCalls: false, |
27
|
|
|
throwOnLostContext: true |
28
|
|
|
} |
29
|
|
|
}, |
30
|
|
|
state: { |
31
|
|
|
terminate: { |
32
|
|
|
calls: 0 |
33
|
|
|
}, |
34
|
|
|
listeners: {}, |
35
|
|
|
log: { |
36
|
|
|
listeners: [], |
37
|
|
|
events: [], |
38
|
|
|
customData: [] |
39
|
|
|
} |
40
|
|
|
}, |
41
|
|
|
handlers: { |
42
|
|
|
terminate: function (self) { |
43
|
|
|
var count = ++self._state.terminate.calls |
44
|
|
|
var message |
45
|
|
|
if (self._settings.terminate.throwOnMultipleCalls && count > 1) { |
46
|
|
|
message = 'VoxEngine.terminate has been called ' + count + ' times, ' + |
47
|
|
|
'which is forbidden by settings' |
48
|
|
|
throw new Error(message) |
49
|
|
|
} |
50
|
|
|
if (self !== this && self._settings.terminate.throwOnLostContext) { |
51
|
|
|
message = 'It seems like `VoxEngine.terminate` has been called ' + |
52
|
|
|
'unbounded and lost it\'s `this`. Please ensure that you are not ' + |
53
|
|
|
'passing `VoxEngine.terminate` as callback ' + |
54
|
|
|
'(`VoxEngine.terminate.bind(VoxEngine)` should do the trick) ' + |
55
|
|
|
'and not storing it in and then calling from a variable.' |
56
|
|
|
throw new Error(message) |
57
|
|
|
} |
58
|
|
|
}, |
59
|
|
|
customData: function (self, data) { |
60
|
|
|
if (arguments.length > 1) { |
61
|
|
|
self._state.log.customData.push(data) |
62
|
|
|
self._state.customData = data |
63
|
|
|
return data |
64
|
|
|
} |
65
|
|
|
if (self._state.hasOwnProperty('customData')) { |
66
|
|
|
return self._state.customData |
67
|
|
|
} |
68
|
|
|
return self._settings.customData.default |
69
|
|
|
}, |
70
|
|
|
addEventListener: function (self, event, handler) { |
71
|
|
|
var listeners = self._state.listeners |
72
|
|
|
if (!listeners[event.name]) { |
73
|
|
|
listeners[event.name] = [] |
74
|
|
|
} |
75
|
|
|
var entry = {event: event.name, action: 'add', handler: handler} |
76
|
|
|
self._state.log.listeners.push(entry) |
77
|
|
|
listeners[event.name].push(handler) |
78
|
|
|
}, |
79
|
|
|
removeEventListener: function (self, event, handler) { |
80
|
|
|
var listeners = self._state.listeners |
81
|
|
|
if (arguments.length === 2) { |
82
|
|
|
self._state.log.listeners.push({event: event.name, action: 'purge'}) |
83
|
|
|
delete listeners[event.name] |
84
|
|
|
return |
85
|
|
|
} |
86
|
|
|
var entry = {event: event.name, action: 'remove', handler: handler} |
87
|
|
|
self._state.log.listeners.push(entry) |
88
|
|
|
var handlers = listeners[event.name] || [] |
89
|
|
|
var index = handlers.indexOf(handler) |
90
|
|
|
if (index === -1) { |
91
|
|
|
return null |
92
|
|
|
} |
93
|
|
|
var value = handlers.splice(index, 1)[0] |
94
|
|
|
if (handlers.length === 0) { |
95
|
|
|
delete listeners[event.name] |
96
|
|
|
} |
97
|
|
|
return value |
98
|
|
|
}, |
99
|
|
|
_emit: function (self, event) { |
100
|
|
|
var listeners = self._state.listeners[event.name] || [] |
101
|
|
|
listeners.forEach(function (listener) { |
102
|
|
|
listener(event) |
103
|
|
|
}) |
104
|
|
|
self._state.log.events.push(event) |
105
|
|
|
} |
106
|
|
|
}, |
107
|
|
|
onFlush: function (self) { |
108
|
|
|
var allure = self._settings.allure |
109
|
|
|
if (!allure.enabled || !global.allure) { |
110
|
|
|
return |
111
|
|
|
} |
112
|
|
|
function attach (type, content) { |
113
|
|
|
var filename = allure[type].filename |
114
|
|
|
var mimeType = allure[type].mimeType |
115
|
|
|
global.allure.createAttachment(filename, Yaml.dump(content), mimeType) |
116
|
|
|
} |
117
|
|
|
var customData = self._state.log.customData |
118
|
|
|
if (customData.length > 0) { |
119
|
|
|
attach('customData', customData) |
120
|
|
|
} |
121
|
|
|
var events = self._state.log.events |
122
|
|
|
if (events.length > 0) { |
123
|
|
|
attach('events', events) |
124
|
|
|
} |
125
|
|
|
var listeners = self._state.log.listeners |
126
|
|
|
if (listeners.length > 0) { |
127
|
|
|
listeners = listeners.map(function (entry) { |
128
|
|
|
entry = Objects.copy(entry) |
129
|
|
|
if (entry.handler) { |
130
|
|
|
entry.handler = entry.handler.name || entry.handler.toString() |
131
|
|
|
} |
132
|
|
|
}) |
133
|
|
|
attach('listeners', listeners) |
134
|
|
|
} |
135
|
|
|
} |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
module.exports = { |
139
|
|
|
VoxEngine: Factory.create('VoxEngine', definition) |
140
|
|
|
} |
141
|
|
|
|