spectre-core 1.11.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/exe/spectre +516 -524
- data/lib/spectre/assertion.rb +33 -14
- data/lib/spectre/bag.rb +21 -19
- data/lib/spectre/curl.rb +397 -391
- data/lib/spectre/diagnostic.rb +39 -29
- data/lib/spectre/environment.rb +30 -26
- data/lib/spectre/helpers.rb +133 -134
- data/lib/spectre/http/basic_auth.rb +5 -2
- data/lib/spectre/http/keystone.rb +76 -73
- data/lib/spectre/http.rb +82 -76
- data/lib/spectre/logger/console.rb +143 -142
- data/lib/spectre/logger/file.rb +1 -1
- data/lib/spectre/logger.rb +3 -1
- data/lib/spectre/mixin.rb +58 -34
- data/lib/spectre/reporter/console.rb +102 -104
- data/lib/spectre/reporter/junit.rb +100 -100
- data/lib/spectre/resources.rb +49 -46
- data/lib/spectre.rb +440 -438
- metadata +3 -3
data/lib/spectre/http.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative '../spectre'
|
2
|
+
|
1
3
|
require 'net/http'
|
2
4
|
require 'openssl'
|
3
5
|
require 'json'
|
@@ -5,7 +7,6 @@ require 'securerandom'
|
|
5
7
|
require 'logger'
|
6
8
|
require 'ostruct'
|
7
9
|
|
8
|
-
|
9
10
|
module Spectre
|
10
11
|
module Http
|
11
12
|
DEFAULT_HTTP_CONFIG = {
|
@@ -19,11 +20,16 @@ module Spectre
|
|
19
20
|
'headers' => nil,
|
20
21
|
'query' => nil,
|
21
22
|
'content_type' => '',
|
22
|
-
}
|
23
|
+
}.freeze
|
23
24
|
|
24
25
|
@@modules = []
|
25
26
|
|
26
27
|
class SpectreHttpRequest < Spectre::DslClass
|
28
|
+
class Headers
|
29
|
+
CONTENT_TYPE = 'Content-Type'
|
30
|
+
UNIQUE_HEADERS = [CONTENT_TYPE].freeze
|
31
|
+
end
|
32
|
+
|
27
33
|
def initialize request
|
28
34
|
@__req = request
|
29
35
|
end
|
@@ -40,25 +46,30 @@ module Spectre
|
|
40
46
|
@__req['path'] = url_path
|
41
47
|
end
|
42
48
|
|
49
|
+
def timeout seconds
|
50
|
+
@__req['timeout'] = seconds
|
51
|
+
end
|
52
|
+
|
43
53
|
def header name, value
|
44
|
-
@__req['headers']
|
54
|
+
@__req['headers'] ||= []
|
45
55
|
@__req['headers'].append [name, value.to_s.strip]
|
46
56
|
end
|
47
57
|
|
48
58
|
def param name, value
|
49
|
-
@__req['query']
|
59
|
+
@__req['query'] ||= []
|
50
60
|
@__req['query'].append [name, value.to_s.strip]
|
51
61
|
end
|
52
62
|
|
53
63
|
def content_type media_type
|
54
|
-
@__req['
|
55
|
-
@__req['headers'].append ['Content-Type', media_type]
|
64
|
+
@__req['content_type'] = media_type
|
56
65
|
end
|
57
66
|
|
58
67
|
def json data
|
59
68
|
data = data.to_h if data.is_a? OpenStruct
|
60
69
|
body JSON.pretty_generate(data)
|
61
|
-
|
70
|
+
|
71
|
+
# TODO: Only set content type, if not explicitly set
|
72
|
+
content_type('application/json')
|
62
73
|
end
|
63
74
|
|
64
75
|
def body body_content
|
@@ -77,9 +88,12 @@ module Spectre
|
|
77
88
|
@__req['auth'] = method
|
78
89
|
end
|
79
90
|
|
91
|
+
def no_auth!
|
92
|
+
@__req['auth'] = 'none'
|
93
|
+
end
|
94
|
+
|
80
95
|
def certificate path
|
81
96
|
@__req['cert'] = path
|
82
|
-
use_ssl!
|
83
97
|
end
|
84
98
|
|
85
99
|
def use_ssl!
|
@@ -101,7 +115,8 @@ module Spectre
|
|
101
115
|
end
|
102
116
|
|
103
117
|
def [] key
|
104
|
-
return nil
|
118
|
+
return nil unless @headers.key?(key.downcase)
|
119
|
+
|
105
120
|
@headers[key.downcase].first
|
106
121
|
end
|
107
122
|
|
@@ -111,52 +126,30 @@ module Spectre
|
|
111
126
|
end
|
112
127
|
|
113
128
|
class SpectreHttpResponse
|
114
|
-
|
115
|
-
@res = res
|
116
|
-
@data = nil
|
117
|
-
@headers = SpectreHttpHeader.new @res[:headers]
|
118
|
-
end
|
119
|
-
|
120
|
-
def code
|
121
|
-
@res[:code]
|
122
|
-
end
|
123
|
-
|
124
|
-
def message
|
125
|
-
@res[:message]
|
126
|
-
end
|
129
|
+
attr_reader :code, :message, :headers, :body
|
127
130
|
|
128
|
-
def
|
129
|
-
@
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
@
|
131
|
+
def initialize net_res
|
132
|
+
@code = net_res.code.to_i
|
133
|
+
@message = net_res.message
|
134
|
+
@body = net_res.body
|
135
|
+
@headers = SpectreHttpHeader.new(net_res.to_hash)
|
136
|
+
@json_data = nil
|
134
137
|
end
|
135
138
|
|
136
139
|
def json
|
137
|
-
|
138
|
-
|
139
|
-
if @data == nil
|
140
|
+
if !@body.nil? and @json_data.nil?
|
140
141
|
begin
|
141
|
-
@
|
142
|
-
rescue
|
143
|
-
raise "Body content is not a valid JSON:\n#{@
|
142
|
+
@json_data = JSON.parse(@body, object_class: OpenStruct)
|
143
|
+
rescue JSON::ParserError
|
144
|
+
raise "Body content is not a valid JSON:\n#{@body}"
|
144
145
|
end
|
145
146
|
end
|
146
147
|
|
147
|
-
@
|
148
|
+
@json_data
|
148
149
|
end
|
149
150
|
|
150
151
|
def success?
|
151
|
-
@
|
152
|
-
end
|
153
|
-
|
154
|
-
def to_s
|
155
|
-
@res.to_s
|
156
|
-
end
|
157
|
-
|
158
|
-
def pretty
|
159
|
-
@res.pretty
|
152
|
+
@code < 400
|
160
153
|
end
|
161
154
|
end
|
162
155
|
|
@@ -172,35 +165,38 @@ module Spectre
|
|
172
165
|
http(name, secure: true, &block)
|
173
166
|
end
|
174
167
|
|
175
|
-
def http name, secure:
|
168
|
+
def http name, secure: false, &block
|
176
169
|
req = {}
|
177
170
|
|
178
171
|
if @@http_cfg.key? name
|
179
|
-
req.
|
180
|
-
raise "No `base_url' set for HTTP client '#{name}'. Check your HTTP config in your environment."
|
172
|
+
req.deep_merge! @@http_cfg[name].deep_clone
|
173
|
+
raise "No `base_url' set for HTTP client '#{name}'. Check your HTTP config in your environment." unless req['base_url']
|
181
174
|
else
|
182
175
|
req['base_url'] = name
|
183
176
|
end
|
184
177
|
|
185
|
-
req['
|
178
|
+
req['use_ssl'] = secure unless secure.nil?
|
186
179
|
|
187
|
-
SpectreHttpRequest.new(req).
|
180
|
+
SpectreHttpRequest.new(req)._evaluate(&block) if block_given?
|
188
181
|
|
189
182
|
invoke(req)
|
190
183
|
end
|
191
184
|
|
192
185
|
def request
|
193
186
|
raise 'No request has been invoked yet' unless @@request
|
187
|
+
|
194
188
|
@@request
|
195
189
|
end
|
196
190
|
|
197
191
|
def response
|
198
192
|
raise 'There is no response. No request has been invoked yet.' unless @@response
|
193
|
+
|
199
194
|
@@response
|
200
195
|
end
|
201
196
|
|
202
197
|
def register mod
|
203
198
|
raise 'Module must not be nil' unless mod
|
199
|
+
|
204
200
|
@@modules << mod
|
205
201
|
end
|
206
202
|
|
@@ -211,7 +207,7 @@ module Spectre
|
|
211
207
|
|
212
208
|
begin
|
213
209
|
json = JSON.parse(str)
|
214
|
-
json.obfuscate!(@@secure_keys)
|
210
|
+
json.obfuscate!(@@secure_keys) unless @@debug
|
215
211
|
|
216
212
|
if pretty
|
217
213
|
str = JSON.pretty_generate(json)
|
@@ -225,14 +221,14 @@ module Spectre
|
|
225
221
|
str
|
226
222
|
end
|
227
223
|
|
228
|
-
def
|
229
|
-
@@secure_keys.any? { |x| key.to_s.downcase.include? x.downcase
|
224
|
+
def secure? key
|
225
|
+
@@secure_keys.any? { |x| key.to_s.downcase.include? x.downcase }
|
230
226
|
end
|
231
227
|
|
232
228
|
def header_to_s headers
|
233
229
|
s = ''
|
234
230
|
headers.each_header.each do |header, value|
|
235
|
-
value = '*****' if
|
231
|
+
value = '*****' if secure?(header) and not @@debug
|
236
232
|
s += "#{header.to_s.ljust(30, '.')}: #{value.to_s}\n"
|
237
233
|
end
|
238
234
|
s
|
@@ -241,36 +237,39 @@ module Spectre
|
|
241
237
|
def invoke req
|
242
238
|
@@request = nil
|
243
239
|
|
244
|
-
|
245
|
-
scheme = 'https'
|
246
|
-
else
|
247
|
-
scheme = 'http'
|
248
|
-
end
|
240
|
+
# Build URI
|
249
241
|
|
242
|
+
scheme = req['use_ssl'] ? 'https' : 'http'
|
250
243
|
base_url = req['base_url']
|
251
244
|
|
252
|
-
|
245
|
+
unless base_url.match /http(?:s)?:\/\//
|
253
246
|
base_url = scheme + '://' + base_url
|
254
247
|
end
|
255
248
|
|
256
249
|
if req['path']
|
257
|
-
base_url = base_url + '/'
|
250
|
+
base_url = base_url + '/' unless base_url.end_with? '/'
|
258
251
|
base_url += req['path']
|
259
252
|
end
|
260
253
|
|
261
254
|
uri = URI(base_url)
|
262
255
|
|
263
|
-
raise "'#{uri}' is not a valid uri"
|
256
|
+
raise "'#{uri}' is not a valid uri" unless uri.host
|
257
|
+
|
258
|
+
# Build query parameters
|
264
259
|
|
265
260
|
uri.query = URI.encode_www_form(req['query']) unless not req['query'] or req['query'].empty?
|
266
261
|
|
262
|
+
# Create HTTP client
|
263
|
+
|
267
264
|
net_http = Net::HTTP.new(uri.host, uri.port)
|
265
|
+
net_http.read_timeout = req['timeout'] || 180
|
268
266
|
|
269
267
|
if uri.scheme == 'https'
|
270
268
|
net_http.use_ssl = true
|
271
269
|
|
272
270
|
if req.key? 'cert'
|
273
271
|
raise "Certificate '#{req['cert']}' does not exist" unless File.exists? req['cert']
|
272
|
+
|
274
273
|
net_http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
275
274
|
net_http.ca_file = req['cert']
|
276
275
|
else
|
@@ -278,6 +277,8 @@ module Spectre
|
|
278
277
|
end
|
279
278
|
end
|
280
279
|
|
280
|
+
# Create HTTP Request
|
281
|
+
|
281
282
|
net_req = Net::HTTPGenericRequest.new(req['method'], true, true, uri)
|
282
283
|
net_req.body = req['body']
|
283
284
|
net_req.content_type = req['content_type'] if req['content_type'] and not req['content_type'].empty?
|
@@ -302,14 +303,23 @@ module Spectre
|
|
302
303
|
req_log += header_to_s(net_req)
|
303
304
|
req_log += try_format_json(req['body'], pretty: true) if req['body'] != nil and not req['body'].empty?
|
304
305
|
|
305
|
-
@@logger.info
|
306
|
+
@@logger.info(req_log)
|
306
307
|
|
307
308
|
# Request
|
308
309
|
|
309
310
|
start_time = Time.now
|
310
|
-
|
311
|
+
|
312
|
+
begin
|
313
|
+
net_res = net_http.request(net_req)
|
314
|
+
rescue SocketError => e
|
315
|
+
raise "The request '#{req['method']} #{uri}' failed. Please check if the given URL '#{uri}' is valid and available or a corresponding HTTP config in the environment file exists. See log for more details. Original.\nOriginal error was: #{e.message}"
|
316
|
+
end
|
317
|
+
|
311
318
|
end_time = Time.now
|
312
319
|
|
320
|
+
req['started_at'] = start_time
|
321
|
+
req['finished_at'] = end_time
|
322
|
+
|
313
323
|
# Run HTTP modules
|
314
324
|
|
315
325
|
@@modules.each do |mod|
|
@@ -320,27 +330,23 @@ module Spectre
|
|
320
330
|
|
321
331
|
res_log = "[<] #{req_id} #{net_res.code} #{net_res.message} (#{end_time - start_time}s)\n"
|
322
332
|
res_log += header_to_s(net_res)
|
323
|
-
res_log += try_format_json(net_res.body, pretty: true)
|
333
|
+
res_log += try_format_json(net_res.body, pretty: true) unless net_res.body.nil? or net_res.body.empty?
|
324
334
|
|
325
335
|
@@logger.info(res_log)
|
326
336
|
|
327
|
-
if req['ensure_success']
|
328
|
-
|
329
|
-
|
330
|
-
end
|
337
|
+
fail "Response code of #{req_id} did not indicate success: #{net_res.code} #{net_res.message}" if req['ensure_success'] and net_res.code.to_i >= 400
|
338
|
+
|
339
|
+
# Set global request and response variables
|
331
340
|
|
332
341
|
@@request = OpenStruct.new(req)
|
333
|
-
@@
|
334
|
-
|
335
|
-
|
336
|
-
headers: net_res.to_hash,
|
337
|
-
body: net_res.body
|
338
|
-
})
|
342
|
+
@@request.freeze
|
343
|
+
|
344
|
+
@@response = SpectreHttpResponse.new(net_res)
|
339
345
|
end
|
340
346
|
end
|
341
347
|
|
342
348
|
Spectre.register do |config|
|
343
|
-
@@logger = ::Logger.new
|
349
|
+
@@logger = ::Logger.new(config['log_file'], progname: 'spectre/http')
|
344
350
|
@@secure_keys = config['secure_keys'] || []
|
345
351
|
@@debug = config['debug']
|
346
352
|
|
@@ -355,4 +361,4 @@ module Spectre
|
|
355
361
|
|
356
362
|
Spectre.delegate :http, :https, :request, :response, to: self
|
357
363
|
end
|
358
|
-
end
|
364
|
+
end
|
@@ -1,142 +1,143 @@
|
|
1
|
-
require 'ectoplasm'
|
2
|
-
|
3
|
-
module Spectre
|
4
|
-
module Logger
|
5
|
-
class Console
|
6
|
-
def initialize config
|
7
|
-
raise 'No log format section in config for console logger' unless config.key? 'log_format' and config['log_format'].key? 'console'
|
8
|
-
|
9
|
-
@config = config['log_format']['console']
|
10
|
-
@indent = @config['indent'] || 2
|
11
|
-
@width = @config['width'] || 80
|
12
|
-
@fmt_end_context = @config['end_context']
|
13
|
-
@fmt_sep = @config['separator']
|
14
|
-
@fmt_start_group = @config['start_group']
|
15
|
-
@fmt_end_group = @config['end_group']
|
16
|
-
|
17
|
-
@process = nil
|
18
|
-
@level = 0
|
19
|
-
end
|
20
|
-
|
21
|
-
def start_subject subject
|
22
|
-
puts subject.desc.blue
|
23
|
-
end
|
24
|
-
|
25
|
-
def start_context context
|
26
|
-
return unless context.__desc
|
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
|
-
puts
|
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
|
-
status = status.
|
83
|
-
status = status.
|
84
|
-
status = status.
|
85
|
-
status = status.
|
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
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
line
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
end
|
1
|
+
require 'ectoplasm'
|
2
|
+
|
3
|
+
module Spectre
|
4
|
+
module Logger
|
5
|
+
class Console
|
6
|
+
def initialize config
|
7
|
+
raise 'No log format section in config for console logger' unless config.key? 'log_format' and config['log_format'].key? 'console'
|
8
|
+
|
9
|
+
@config = config['log_format']['console']
|
10
|
+
@indent = @config['indent'] || 2
|
11
|
+
@width = @config['width'] || 80
|
12
|
+
@fmt_end_context = @config['end_context']
|
13
|
+
@fmt_sep = @config['separator']
|
14
|
+
@fmt_start_group = @config['start_group']
|
15
|
+
@fmt_end_group = @config['end_group']
|
16
|
+
|
17
|
+
@process = nil
|
18
|
+
@level = 0
|
19
|
+
end
|
20
|
+
|
21
|
+
def start_subject subject
|
22
|
+
puts subject.desc.blue
|
23
|
+
end
|
24
|
+
|
25
|
+
def start_context context
|
26
|
+
return unless context.__desc
|
27
|
+
|
28
|
+
puts (' ' * indent) + context.__desc.magenta
|
29
|
+
@level += 1
|
30
|
+
end
|
31
|
+
|
32
|
+
def end_context context
|
33
|
+
return unless context.__desc
|
34
|
+
|
35
|
+
@level -= 1
|
36
|
+
puts (' ' * indent) + @fmt_end_context.gsub('<desc>', context.__desc).magenta if @fmt_end_context
|
37
|
+
end
|
38
|
+
|
39
|
+
def start_spec spec, data=nil
|
40
|
+
text = spec.desc
|
41
|
+
text += " with #{data}" if data
|
42
|
+
puts (' ' * indent) + text.cyan
|
43
|
+
|
44
|
+
@level += 1
|
45
|
+
end
|
46
|
+
|
47
|
+
def end_spec _spec, _data
|
48
|
+
@level -= 1
|
49
|
+
end
|
50
|
+
|
51
|
+
def log_separator desc
|
52
|
+
if desc
|
53
|
+
desc = @fmt_sep.gsub('<indent>', ' ' * indent).gsub('<desc>', desc) if @fmt_sep
|
54
|
+
puts desc.blue
|
55
|
+
else
|
56
|
+
puts
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def start_group desc
|
61
|
+
desc = @fmt_start_group.gsub('<desc>', desc) if @fmt_start_group
|
62
|
+
puts (' ' * indent) + desc.blue
|
63
|
+
@level += 1
|
64
|
+
end
|
65
|
+
|
66
|
+
def end_group desc
|
67
|
+
if desc and @fmt_start_group
|
68
|
+
desc = @fmt_start_group.gsub('<desc>', desc) if @fmt_start_group
|
69
|
+
puts (' ' * indent) + desc.blue
|
70
|
+
end
|
71
|
+
|
72
|
+
@level -= 1
|
73
|
+
end
|
74
|
+
|
75
|
+
def log_process desc
|
76
|
+
print_line(desc)
|
77
|
+
@process = desc
|
78
|
+
@level += 1
|
79
|
+
end
|
80
|
+
|
81
|
+
def log_status _desc, status, annotation=nil
|
82
|
+
status = status.green if status == Status::OK
|
83
|
+
status = status.blue if status == Status::INFO
|
84
|
+
status = status.grey if status == Status::DEBUG
|
85
|
+
status = status.red if status == Status::FAILED
|
86
|
+
status = status.red if status == Status::ERROR
|
87
|
+
status = status.grey if status == Status::SKIPPED
|
88
|
+
|
89
|
+
txt = status
|
90
|
+
txt += ' ' + annotation if annotation
|
91
|
+
|
92
|
+
@level -= 1
|
93
|
+
|
94
|
+
if @process
|
95
|
+
puts txt
|
96
|
+
else
|
97
|
+
print_line('', status)
|
98
|
+
end
|
99
|
+
|
100
|
+
@process = nil
|
101
|
+
end
|
102
|
+
|
103
|
+
def log_info message
|
104
|
+
print_line(message, Status::INFO.blue)
|
105
|
+
end
|
106
|
+
|
107
|
+
def log_debug message
|
108
|
+
print_line(message, Status::DEBUG.grey)
|
109
|
+
end
|
110
|
+
|
111
|
+
def log_error _spec, exception
|
112
|
+
txt = (Status::ERROR + ' - ' + exception.class.name).red
|
113
|
+
print_line('', txt)
|
114
|
+
end
|
115
|
+
|
116
|
+
def log_skipped _spec
|
117
|
+
print_line('', Status::SKIPPED.grey)
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def indent
|
123
|
+
(@level+1) * @indent
|
124
|
+
end
|
125
|
+
|
126
|
+
def print_line text='', status=nil
|
127
|
+
puts if @process
|
128
|
+
|
129
|
+
ind = indent
|
130
|
+
line = (' ' * indent) + text
|
131
|
+
remaining = @width - text.length - ind
|
132
|
+
line += '.' * (@width - text.length - ind) if remaining > 0
|
133
|
+
|
134
|
+
print line
|
135
|
+
|
136
|
+
if status
|
137
|
+
puts status
|
138
|
+
@process = nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
data/lib/spectre/logger/file.rb
CHANGED
data/lib/spectre/logger.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require_relative '../spectre'
|
1
2
|
require 'date'
|
2
3
|
|
3
4
|
module Spectre
|
@@ -98,6 +99,7 @@ module Spectre
|
|
98
99
|
|
99
100
|
def log_debug message
|
100
101
|
return unless @@debug
|
102
|
+
|
101
103
|
add_log(message)
|
102
104
|
delegate(:log_debug, message)
|
103
105
|
end
|
@@ -141,4 +143,4 @@ module Spectre
|
|
141
143
|
|
142
144
|
Spectre.delegate :log, :info, :debug, :group, :separate, to: self
|
143
145
|
end
|
144
|
-
end
|
146
|
+
end
|