spectre-core 1.10.0 → 1.11.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76697e95cde1f8359db1f305ba1d15869bd53903d49a0575fa1ee6f2cda7bf98
4
- data.tar.gz: 72562ba547d8f8ff68e880d8f196bd31c7da8f1fd5639231bb56aa838830879a
3
+ metadata.gz: 8333942c6050c7adf1bb9c238538b5364b5648514264612aefc161f715c48e58
4
+ data.tar.gz: 34ca46ef693108549a69c754bc3b22d5be33e642d9a6dfde040b664af47cfe58
5
5
  SHA512:
6
- metadata.gz: e1ce860bd80ee58af11d506ad9e297f9a432a6f71f62b7702574c5dd52af0f6a6de7fa8bd2e35c167e387e063f86f97a77f51e0541399a866133c0a3524b22a9
7
- data.tar.gz: eebfbac67335a7663f407a26094336ee9815a02ebe74789b82254a45ca6539ccc036f289a3eed37cfc581b8e178986f70cbdf5d3c1af49a657ebce4c9ce7246b
6
+ metadata.gz: a840c8d9afd7010e0873cf273400a8a5d82b28ad05941d1c4562c03a8aed60fabc7ed704dc2538c5960a940440204df0228d0ce77b6ee11ec68f820c3deb6954
7
+ data.tar.gz: f6913fa578a938341fbd15455c1e122a4c425bacb68d1353ce7c5f0c8ed96b206eba2625d28d1d8df91fec4161343a28b15db5535c3785000c88cbee914c0f2b
data/exe/spectre CHANGED
@@ -238,6 +238,10 @@ cfg.merge! env if env
238
238
 
239
239
  String.colored! if cfg['colored']
240
240
 
241
+ # Load environment exlicitly before loading specs to make it available in spec definition
242
+ require_relative '../lib/spectre/environment' unless cfg['exclude'].include? 'spectre/environment'
243
+ Spectre.configure(cfg)
244
+
241
245
 
242
246
  ###########################################
243
247
  # Load Specs
@@ -260,7 +264,7 @@ if action == 'list'
260
264
  colors = [:blue, :magenta, :yellow, :green]
261
265
  specs = Spectre.specs(cfg['specs'], cfg['tags'])
262
266
 
263
- exit 1 if specs.length == 0
267
+ exit 1 unless specs.any?
264
268
 
265
269
  counter = 0
266
270
 
@@ -300,6 +304,7 @@ if action == 'run'
300
304
  FileUtils.makedirs log_dir if !Dir.exists? log_dir
301
305
 
302
306
  # Load Modules
307
+
303
308
  cfg['modules']
304
309
  .concat(cfg['include'])
305
310
  .select { |mod| !cfg['exclude'].include? mod }
@@ -323,6 +328,14 @@ if action == 'run'
323
328
  end
324
329
  end
325
330
 
331
+ # Load mixins
332
+
333
+ cfg['mixin_patterns'].each do |pattern|
334
+ Dir.glob(pattern).each do|f|
335
+ require_relative File.join(Dir.pwd, f)
336
+ end
337
+ end
338
+
326
339
  Spectre.configure(cfg)
327
340
 
328
341
  Spectre::Logger.debug! if cfg['debug']
@@ -334,7 +347,7 @@ if action == 'run'
334
347
 
335
348
  specs = Spectre.specs(cfg['specs'], cfg['tags'])
336
349
 
337
- if specs.length == 0
350
+ if not specs.any?
338
351
  puts "No specs found in #{Dir.pwd}"
339
352
  exit 1
340
353
  end
@@ -348,7 +361,7 @@ if action == 'run'
348
361
 
349
362
  errors = run_infos.select { |x| x.error != nil or x.failure != nil }
350
363
 
351
- exit 0 if cfg['ignore_failure'] or errors.count == 0
364
+ exit 0 if cfg['ignore_failure'] or not errors.any?
352
365
 
353
366
  exit 1
354
367
  end
@@ -360,7 +373,7 @@ end
360
373
 
361
374
 
362
375
  if action == 'envs'
363
- exit 1 if envs.length == 0
376
+ exit 1 unless envs.any?
364
377
  puts envs.pretty
365
378
  exit 0
366
379
  end
@@ -10,7 +10,7 @@ module Spectre
10
10
  end
11
11
 
12
12
  def should_be_empty
13
- raise AssertionFailure.new("The value '#{self.to_s.trim}' should be empty", nil, self) unless self == nil
13
+ raise AssertionFailure.new("The value '#{self.to_s.trim}' should be empty", nil, self) unless self.nil?
14
14
  end
15
15
 
16
16
  def should_not_be(val)
@@ -91,11 +91,11 @@ module Spectre
91
91
  end
92
92
 
93
93
  def should_be_empty
94
- raise AssertionFailure.new('empty list', self) unless self.length == 0
94
+ raise AssertionFailure.new('empty list', self) unless self.empty?
95
95
  end
96
96
 
97
97
  def should_not_be_empty
98
- raise AssertionFailure.new('no empty list', self) unless self.length > 0
98
+ raise AssertionFailure.new('no empty list', self) if self.empty?
99
99
  end
100
100
  end
101
101
 
data/lib/spectre/curl.rb CHANGED
@@ -192,7 +192,8 @@ module Spectre::Curl
192
192
  return str unless str or str.empty?
193
193
 
194
194
  begin
195
- json = JSON.parse str
195
+ json = JSON.parse(str)
196
+ json.obfuscate!(@@secure_keys) if not @@debug
196
197
 
197
198
  if pretty
198
199
  str = JSON.pretty_generate(json)
@@ -206,6 +207,25 @@ module Spectre::Curl
206
207
  str
207
208
  end
208
209
 
210
+ def is_secure? key
211
+ @@secure_keys.any? { |x| key.to_s.downcase.include? x.downcase }
212
+ end
213
+
214
+ def header_to_s headers
215
+ s = ''
216
+
217
+ return s unless headers
218
+
219
+ headers.each do |header|
220
+ key = header[0].to_s
221
+ value = header[1].to_s
222
+ value = '*****' if is_secure?(key) and not @@debug
223
+ s += "#{key.ljust(30, '.')}: #{value}\n"
224
+ end
225
+
226
+ s
227
+ end
228
+
209
229
  def invoke req
210
230
  cmd = [@@curl_path]
211
231
 
@@ -230,11 +250,11 @@ module Spectre::Curl
230
250
  uri += '?'
231
251
  uri += req['query']
232
252
  .map { |x| x.join '='}
233
- .join '&'
253
+ .join('&')
234
254
  end
235
255
 
236
- cmd.append '"' + uri + '"'
237
- cmd.append '-X', req['method'] unless req['method'] == 'GET' or (req['body'] and req['method'] == 'POST')
256
+ cmd.append('"' + uri + '"')
257
+ cmd.append('-X', req['method']) unless req['method'] == 'GET' or (req['body'] and req['method'] == 'POST')
238
258
 
239
259
  # Call all registered modules
240
260
  @@modules.each do |mod|
@@ -243,43 +263,41 @@ module Spectre::Curl
243
263
 
244
264
  # Add headers to curl command
245
265
  req['headers'].each do |header|
246
- cmd.append '-H', '"' + header.join(':') + '"'
266
+ cmd.append('-H', '"' + header.join(':') + '"')
247
267
  end if req['headers']
248
268
 
249
269
  # Add request body
250
270
  if req['body'] != nil and not req['body'].empty?
251
271
  req_body = try_format_json(req['body']).gsub(/"/, '\\"')
252
- cmd.append '-d', '"' + req_body + '"'
272
+ cmd.append('-d', '"' + req_body + '"')
253
273
  elsif ['POST', 'PUT', 'PATCH'].include? req['method'].upcase
254
- cmd.append '-d', '"\n"'
274
+ cmd.append('-d', '"\n"')
255
275
  end
256
276
 
257
277
  # Add certificate path if one if given
258
278
  if req['cert']
259
279
  raise "Certificate '#{req['cert']}' does not exist" unless File.exists? req['cert']
260
- cmd.append '--cacert', req['cert']
280
+ cmd.append('--cacert', req['cert'])
261
281
  elsif req['use_ssl'] or uri.start_with? 'https'
262
- cmd.append '-k'
282
+ cmd.append('-k')
263
283
  end
264
284
 
265
- cmd.append '-i'
266
- cmd.append '-v'
285
+ cmd.append('-i')
286
+ cmd.append('-v')
267
287
 
268
- @@request = OpenStruct.new req
288
+ @@request = OpenStruct.new(req)
269
289
 
270
- sys_cmd = cmd.join ' '
290
+ sys_cmd = cmd.join(' ')
271
291
 
272
- @@logger.debug sys_cmd
292
+ @@logger.debug(sys_cmd)
273
293
 
274
294
  req_id = SecureRandom.uuid()[0..5]
275
295
 
276
296
  req_log = "[>] #{req_id} #{req['method']} #{uri}\n"
277
- req['headers'].each do |header|
278
- req_log += "#{header[0].to_s.ljust(30, '.')}: #{header[1].to_s}\n"
279
- end if req['headers']
280
- req_log += req['body'] if req['body'] != nil and not req['body'].empty?
297
+ req_log += header_to_s(req['headers'])
298
+ req_log += try_format_json(req['body'], pretty: true)
281
299
 
282
- @@logger.info req_log
300
+ @@logger.info(req_log)
283
301
 
284
302
  start_time = Time.now
285
303
 
@@ -297,7 +315,7 @@ module Spectre::Curl
297
315
 
298
316
  raise "Unable to request #{uri}. Please check if this service is reachable." unless output
299
317
 
300
- @@logger.debug "[<] #{req_id} stdout:\n#{output}"
318
+ @@logger.debug("[<] #{req_id} stdout:\n#{output}")
301
319
 
302
320
  header, body = output.split /\r?\n\r?\n/
303
321
 
@@ -342,7 +360,7 @@ module Spectre::Curl
342
360
 
343
361
  @@logger.info res_log
344
362
 
345
- @@response = SpectreHttpResponse.new res
363
+ @@response = SpectreHttpResponse.new(res)
346
364
 
347
365
  raise "Response did not indicate success: #{@@response.code} #{@@response.message}" if req['ensure_success'] and not @@response.success?
348
366
 
@@ -351,7 +369,12 @@ module Spectre::Curl
351
369
  end
352
370
 
353
371
  Spectre.register do |config|
354
- @@logger = ::Logger.new config['log_file'], progname: 'spectre/curl'
372
+ @@debug = config['debug']
373
+
374
+ @@logger = ::Logger.new(config['log_file'], progname: 'spectre/curl')
375
+ @@logger.level = @@debug ? Logger::DEBUG : Logger::INFO
376
+
377
+ @@secure_keys = config['secure_keys'] || []
355
378
 
356
379
  @@curl_path = config['curl_path'] || 'curl'
357
380
 
@@ -13,15 +13,8 @@ class ::String
13
13
  DateTime.parse(self)
14
14
  end
15
15
 
16
- def content with: nil
17
- fail "'#{self}' is not a file path, or the file does not exist." if !File.exists? self
18
- file_content = File.read(self)
19
-
20
- if with
21
- file_content.with(with)
22
- else
23
- file_content
24
- end
16
+ def as_timestamp
17
+ DateTime.parse(self).to_time.to_i
25
18
  end
26
19
 
27
20
  def with mapping
@@ -30,25 +23,15 @@ class ::String
30
23
  new_string = self
31
24
 
32
25
  mapping.each do |key, value|
33
- new_string = new_string.gsub '#{' + key.to_s + '}', value.to_s
26
+ new_string = new_string.gsub('#{' + key.to_s + '}', value.to_s)
34
27
  end
35
28
 
36
29
  new_string
37
30
  end
38
31
 
39
- def exists?
40
- File.exists? self
41
- end
42
-
43
- def remove!
44
- fail "'#{self}' is not a file path, or the file does not exist." if !File.exists? self
45
-
46
- File.delete self
47
- end
48
-
49
- def trim count = 50
50
- if (self.length + 3) > count
51
- return self[0..count-4] + '...'
32
+ def trim size = 50
33
+ if (self.length + 3) > size
34
+ return self[0..size-4] + '...'
52
35
  end
53
36
 
54
37
  self
@@ -64,6 +47,33 @@ class ::String
64
47
  # do nothing and return nil
65
48
  end
66
49
  end
50
+
51
+ # File helpers
52
+
53
+ def content with: nil
54
+ fail "'#{self}' is not a file path, or the file does not exist." if !File.exists? self
55
+ file_content = File.read(self)
56
+
57
+ if with
58
+ file_content.with(with)
59
+ else
60
+ file_content
61
+ end
62
+ end
63
+
64
+ def file_size
65
+ fail "'#{self}' is not a file path, or the file does not exist." if !File.exists? self
66
+ File.size(self)
67
+ end
68
+
69
+ def exists?
70
+ File.exists? self
71
+ end
72
+
73
+ def remove!
74
+ fail "'#{self}' is not a file path, or the file does not exist." if !File.exists? self
75
+ File.delete self
76
+ end
67
77
  end
68
78
 
69
79
 
@@ -77,6 +87,16 @@ class ::OpenStruct
77
87
 
78
88
  JsonPath.on(self, path)
79
89
  end
90
+
91
+ def default_to! defaults
92
+ defaults.each_key do |key|
93
+ if not self[key] != nil
94
+ self[key] = defaults[key]
95
+ end
96
+ end
97
+ end
98
+
99
+ alias :defaults_to! :default_to!
80
100
  end
81
101
 
82
102
 
@@ -84,9 +104,31 @@ class ::Hash
84
104
  def symbolize_keys
85
105
  self.inject({}) { |memo, (k,v)| memo[k.to_sym] = v; memo }
86
106
  end
107
+
108
+ def default_to! defaults
109
+ defaults.each_key do |key|
110
+ if not self[key] != nil
111
+ self[key] = defaults[key]
112
+ end
113
+ end
114
+ end
115
+
116
+ alias :defaults_to! :default_to!
117
+ end
118
+
119
+
120
+ class ::Array
121
+ def last
122
+ self[-1]
123
+ end
87
124
  end
88
125
 
89
126
 
90
127
  def uuid length = 5
91
128
  SecureRandom.uuid().gsub('-', '')[0..length-1]
129
+ end
130
+
131
+
132
+ def now
133
+ Time.now
92
134
  end
data/lib/spectre/mixin.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'ostruct'
2
+ require 'spectre/logger'
2
3
 
3
4
  module Spectre
4
5
  module Mixin
@@ -11,12 +12,16 @@ module Spectre
11
12
 
12
13
  def run desc, with: []
13
14
  raise "no mixin with desc '#{desc}' defined" unless @@mixins.key? desc
14
- Logger.log_debug "running mixin '#{desc}'"
15
+ Spectre::Logger.log_debug "running mixin '#{desc}'"
15
16
 
16
- if with.is_a? Array
17
- @@mixins[desc].call *with
17
+ params = with || {}
18
+
19
+ if params.is_a? Array
20
+ @@mixins[desc].call *params
21
+ elsif params.is_a? Hash
22
+ @@mixins[desc].call OpenStruct.new(params)
18
23
  else
19
- @@mixins[desc].call with
24
+ @@mixins[desc].call params
20
25
  end
21
26
  end
22
27
 
@@ -24,18 +29,6 @@ module Spectre
24
29
  alias_method :step, :run
25
30
  end
26
31
 
27
- Spectre.register do |config|
28
- if not config.key? 'mixin_patterns'
29
- return
30
- end
31
-
32
- config['mixin_patterns'].each do |pattern|
33
- Dir.glob(pattern).each do|f|
34
- require_relative File.join(Dir.pwd, f)
35
- end
36
- end
37
- end
38
-
39
32
  Spectre.delegate :mixin, :run, :also, :step, to: Mixin
40
33
  end
41
34
  end
@@ -57,6 +57,7 @@ module Spectre::Reporter
57
57
 
58
58
  if run_info.log.count > 0 or run_info.properties.count > 0 or run_info.data
59
59
  xml_str += '<system-out>'
60
+ xml_str += '<![CDATA['
60
61
 
61
62
  if run_info.properties.count > 0
62
63
  run_info.properties.each do |key, val|
@@ -75,6 +76,7 @@ module Spectre::Reporter
75
76
  xml_str += messages.join("\n")
76
77
  end
77
78
 
79
+ xml_str += ']]>'
78
80
  xml_str += '</system-out>'
79
81
  end
80
82
 
data/lib/spectre.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Spectre
2
2
  module Version
3
3
  MAJOR = 1
4
- MINOR = 10
4
+ MINOR = 11
5
5
  TINY = 0
6
6
  end
7
7
 
@@ -31,20 +31,20 @@ module Spectre
31
31
  # https://www.dan-manges.com/blog/ruby-dsls-instance-eval-with-delegation
32
32
  class DslClass
33
33
  def _evaluate &block
34
- @__bound_self__ = eval 'self', block.binding
34
+ @__bound_self__ = eval('self', block.binding)
35
35
  instance_eval(&block)
36
36
  end
37
37
 
38
38
  def _execute args, &block
39
- @__bound_self__ = eval 'self', block.binding
39
+ @__bound_self__ = eval('self', block.binding)
40
40
  instance_exec(args, &block)
41
41
  end
42
42
 
43
43
  def method_missing method, *args, **kwargs, &block
44
44
  if @__bound_self__.respond_to? method
45
- @__bound_self__.send method, *args, **kwargs, &block
45
+ @__bound_self__.send(method, *args, **kwargs, &block)
46
46
  else
47
- Delegator.redirect method, *args, **kwargs, &block
47
+ Delegator.redirect(method, *args, **kwargs, &block)
48
48
  end
49
49
  end
50
50
  end
@@ -151,7 +151,7 @@ module Spectre
151
151
 
152
152
  begin
153
153
  specs.each do |spec|
154
- if spec.data.length > 0
154
+ if spec.data.any?
155
155
  spec.data.each do |data|
156
156
  Logger.log_spec(spec, data) do
157
157
  runs << run_spec(spec, data)
@@ -208,7 +208,7 @@ module Spectre
208
208
  end
209
209
 
210
210
  def run_spec spec, data=nil
211
- run_info = RunInfo.new spec, data
211
+ run_info = RunInfo.new(spec, data)
212
212
 
213
213
  @@current = run_info
214
214
 
@@ -216,16 +216,16 @@ module Spectre
216
216
 
217
217
  begin
218
218
  if spec.context.__before_blocks.count > 0
219
- before_ctx = SpecContext.new spec.subject, 'before'
219
+ before_ctx = SpecContext.new(spec.subject, 'before')
220
220
 
221
221
  Logger.log_context before_ctx do
222
222
  spec.context.__before_blocks.each do |block|
223
- block.call data
223
+ block.call(data)
224
224
  end
225
225
  end
226
226
  end
227
227
 
228
- spec.block.call data
228
+ spec.block.call(data)
229
229
 
230
230
  rescue ExpectationFailure => e
231
231
  run_info.failure = e
@@ -240,7 +240,7 @@ module Spectre
240
240
 
241
241
  ensure
242
242
  if spec.context.__after_blocks.count > 0
243
- after_ctx = SpecContext.new spec.subject, 'after'
243
+ after_ctx = SpecContext.new(spec.subject, 'after')
244
244
 
245
245
  Logger.log_context after_ctx do
246
246
  begin
@@ -306,7 +306,11 @@ module Spectre
306
306
  .first
307
307
  end
308
308
 
309
- @__subject.add_spec(desc, tags, with, block, self, spec_file)
309
+ raise "`with' has to be an Array" unless with.is_a? Array
310
+
311
+ data = with.map { |x| x.is_a?(Hash) ? OpenStruct.new(x) : x }
312
+
313
+ @__subject.add_spec(desc, tags, data, block, self, spec_file)
310
314
  end
311
315
 
312
316
  def before &block
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spectre-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.0
4
+ version: 1.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Neubauer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-12 00:00:00.000000000 Z
11
+ date: 2021-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ectoplasm