spectre-core 1.12.4 → 1.14.1

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.
@@ -1,4 +1,5 @@
1
1
  require_relative '../spectre'
2
+ require_relative '../spectre/helpers'
2
3
 
3
4
  require 'ostruct'
4
5
  require_relative 'logger'
@@ -7,38 +8,45 @@ require_relative 'logger'
7
8
  module Spectre
8
9
  module Assertion
9
10
  class ::Object
10
- def should_be(val)
11
- raise AssertionFailure.new("The value '#{self.to_s.trim}' should be '#{val.to_s.trim}'", val, self) unless self.to_s == val.to_s
11
+ def should_be(value)
12
+ evaluate(value, "#{self} should be #{value}") do |x|
13
+ self.to_s == x.to_s
14
+ end
12
15
  end
13
16
 
14
17
  def should_be_empty
15
- raise AssertionFailure.new("The value '#{self.to_s.trim}' should be empty", nil, self) unless self.nil?
18
+ raise AssertionFailure.new("#{self.to_s.trim} should be empty", nil, self) unless self.nil?
16
19
  end
17
20
 
18
21
  def should_not_be(val)
19
- raise AssertionFailure.new("The value '#{self.to_s.trim}' should not be '#{val.to_s.trim}'", val, self) unless self.to_s != val.to_s
22
+ raise AssertionFailure.new("#{self.to_s.trim} should not be #{val.to_s.trim}", val, self) unless self.to_s != val.to_s
20
23
  end
21
24
 
22
25
  def should_not_exist
23
- raise AssertionFailure.new("The value '#{self.to_s.trim}' should not exist, but it does", val, self) unless self.to_s != nil
26
+ raise AssertionFailure.new("#{self.to_s.trim} should not exist, but it does", val, self) unless self.to_s != nil
24
27
  end
25
28
 
26
29
  def should_not_be_empty
27
- raise AssertionFailure.new('The value is empty', 'nothing', self) unless self != nil
30
+ raise AssertionFailure.new('empty value', 'nothing', self) unless self != nil
31
+ end
32
+
33
+ def evaluate val, message, &block
34
+ val = Evaluation.new(val) unless val.is_a? Evaluation
35
+ raise AssertionFailure.new(message, val, self) unless val.run &block
28
36
  end
29
37
 
30
38
  def or other
31
- OrEvaluation.new self, other
39
+ OrEvaluation.new(self, other)
32
40
  end
33
41
 
34
42
  def and other
35
- AndEvaluation.new self, other
43
+ AndEvaluation.new(self, other)
36
44
  end
37
45
  end
38
46
 
39
47
  class ::NilClass
40
48
  def should_be(val)
41
- raise AssertionFailure.new("There is nothing, but the value should be '#{val.to_s.trim}'", val, nil) unless val == nil
49
+ raise AssertionFailure.new("Value is empty, but it should be '#{val.to_s.trim}'", val, nil) unless val == nil
42
50
  end
43
51
 
44
52
  def should_be_empty
@@ -52,7 +60,7 @@ module Spectre
52
60
  end
53
61
 
54
62
  def should_not_be_empty
55
- raise AssertionFailure.new('The value does not exist', 'nil')
63
+ raise AssertionFailure.new('Value is empty', 'nil')
56
64
  end
57
65
  end
58
66
 
@@ -66,21 +74,21 @@ module Spectre
66
74
  end
67
75
 
68
76
  def should_be_empty
69
- raise AssertionFailure.new('The object should be empty', nil, self) unless self.empty?
77
+ raise AssertionFailure.new('Object should be empty', nil, self) unless self.empty?
70
78
  end
71
79
 
72
80
  def should_not_be_empty
73
- raise AssertionFailure.new('The object should not be empty', nil, self) if self.empty?
81
+ raise AssertionFailure.new('Object should not be empty', nil, self) if self.empty?
74
82
  end
75
83
  end
76
84
 
77
85
  class ::OpenStruct
78
86
  def should_be_empty
79
- raise AssertionFailure.new('The object should be empty', nil, self) unless self.to_h.empty?
87
+ raise AssertionFailure.new('Object should be empty', nil, self) unless self.to_h.empty?
80
88
  end
81
89
 
82
90
  def should_not_be_empty
83
- raise AssertionFailure.new('The object should not be empty', nil, self) if self.to_h.empty?
91
+ raise AssertionFailure.new('Object should not be empty', nil, self) if self.to_h.empty?
84
92
  end
85
93
  end
86
94
 
@@ -93,7 +101,9 @@ module Spectre
93
101
  val = OpenStruct.new(val)
94
102
  end
95
103
 
96
- raise AssertionFailure.new("The list [#{list.join(', ').trim}] should contain '#{val.to_s.trim}'", val, list) unless list.include? val
104
+ evaluate(val, "#{self} should contain #{val.to_s}") do |x|
105
+ self.include? x
106
+ end
97
107
  end
98
108
 
99
109
  def should_not_contain(val)
@@ -104,57 +114,61 @@ module Spectre
104
114
  val = OpenStruct.new(val)
105
115
  end
106
116
 
107
- raise AssertionFailure.new("The list [#{list.join(', ').trim}] should not contain '#{val.to_s.trim}'", val, list) if list.include? val
117
+ raise AssertionFailure.new("[#{list.join(', ').trim}] should not contain '#{val.to_s.trim}'", val, list) if list.include? val
108
118
  end
109
119
 
110
120
  def should_be_empty
111
- raise AssertionFailure.new('The list is not empty', self) unless self.empty?
121
+ raise AssertionFailure.new('List is not empty', self) unless self.empty?
112
122
  end
113
123
 
114
124
  def should_not_be_empty
115
- raise AssertionFailure.new('The list is empty', self) if self.empty?
125
+ raise AssertionFailure.new('List is empty', self) if self.empty?
116
126
  end
117
127
  end
118
128
 
119
129
  class ::String
120
130
  def should_be(val)
121
- raise AssertionFailure.new("The text '#{self.trim}' should be '#{val.to_s.trim}'", val, self) unless self == val
131
+ evaluate(val, "'#{self}' should be '#{val}'") do |x|
132
+ self.to_s == x.to_s
133
+ end
122
134
  end
123
135
 
124
136
  def should_be_empty
125
- raise AssertionFailure.new("The text '#{self.trim}' should be empty", nil, self) unless self.empty?
137
+ raise AssertionFailure.new("'#{self.trim}' should be empty", nil, self) unless self.empty?
126
138
  end
127
139
 
128
140
  def should_not_be(val)
129
- raise AssertionFailure.new("The text '#{self.trim}' should not be '#{val.to_s.trim}'", val, self) unless self != val
141
+ evaluate(value, "'#{self}' should not be '#{value}'") do |x|
142
+ self.to_s != x.to_s
143
+ end
130
144
  end
131
145
 
132
146
  def should_not_be_empty
133
- raise AssertionFailure.new('The text should not be empty', 'nothing', self) unless not self.empty?
147
+ raise AssertionFailure.new('Text should not be empty', 'nothing', self) unless not self.empty?
134
148
  end
135
149
 
136
- def should_contain(value)
137
- raise AssertionFailure.new("The value is nil") if value.nil?
138
-
139
- predicate = proc { |x| self.include? x.to_s }
140
- evaluation = SingleEvaluation.new(value)
141
- success = evaluation.call(predicate)
142
-
143
- return if success
144
-
145
- raise AssertionFailure.new("The text '#{self.to_s.trim}' should contain #{evaluation.to_s}", evaluation, self)
150
+ def should_contain(val)
151
+ evaluate(val, "'#{self.trim}' should contain '#{val.to_s}'") do |x|
152
+ self.include? x.to_s
153
+ end
146
154
  end
147
155
 
148
156
  def should_not_contain(val)
149
- raise AssertionFailure.new("The text '#{self.trim}' should not contain '#{val.trim}'", val, self) if self.include? val
157
+ evaluate(val, "'#{self}' should not contain '#{val}'") do |x|
158
+ not self.include? x.to_s
159
+ end
150
160
  end
151
161
 
152
162
  def should_match(regex)
153
- raise AssertionFailure.new("The text '#{self.trim}' should match '#{val}'", regex, self) unless self.match(regex)
163
+ evaluate(regex, "'#{self.trim}' should match /#{regex}/") do |x|
164
+ self.match(x)
165
+ end
154
166
  end
155
167
 
156
168
  def should_not_match(regex)
157
- raise AssertionFailure.new("The text '#{self.trim}' should not match '#{val}'", regex, self) if self.match(regex)
169
+ evaluate(regex, "'#{self.trim}' should not match '#{regex}'") do |x|
170
+ not self.match(x)
171
+ end
158
172
  end
159
173
 
160
174
  alias :| :or
@@ -162,62 +176,58 @@ module Spectre
162
176
  end
163
177
 
164
178
  class Evaluation
165
- def initialize value, other
166
- @value = value
167
- @other = other
179
+ def initialize val
180
+ @val = val
181
+ end
182
+
183
+ def run &block
184
+ evaluate(@val, block)
168
185
  end
169
186
 
170
- def eval_assertion predicate, val
187
+ def evaluate(val, predicate)
171
188
  if val.is_a? Evaluation
172
- val.call(predicate)
189
+ val.run &predicate
173
190
  else
174
191
  predicate.call(val)
175
192
  end
176
193
  end
177
194
 
178
- alias :| :or
179
- alias :& :and
180
- end
181
-
182
- class SingleEvaluation < Evaluation
183
- def initialize value
184
- super(value, nil)
185
- end
186
-
187
- def call predicate
188
- eval_assertion(predicate, @value)
189
- end
190
-
191
195
  def to_s
192
- @value.to_s
196
+ @val.to_s
193
197
  end
194
198
  end
195
199
 
196
200
  class OrEvaluation < Evaluation
197
- def initialize value, other
198
- super(value, other)
201
+ def initialize val, other
202
+ @val = val
203
+ @other = other
199
204
  end
200
205
 
201
- def call predicate
202
- eval_assertion(predicate, @value) or eval_assertion(predicate, @other)
206
+ def run &block
207
+ res1 = evaluate(@val, block)
208
+ res2 = evaluate(@other, block)
209
+ res1 or res2
203
210
  end
204
211
 
205
212
  def to_s
206
- "(#{@value.to_s} or #{@other.to_s})"
213
+ "(#{@val} or #{@other})"
207
214
  end
208
215
  end
209
216
 
210
217
  class AndEvaluation < Evaluation
211
- def initialize value, other
212
- super(value, other)
218
+ def initialize val, other
219
+ @val = val
220
+ @other = other
213
221
  end
214
222
 
215
- def call predicate
216
- eval_assertion(predicate, @value) and eval_assertion(predicate, @other)
223
+ def run &block
224
+ res1 = evaluate(@val, block)
225
+ res2 = evaluate(@other, block)
226
+ res1 and res2
217
227
  end
218
228
 
219
229
  def to_s
220
- "(#{@value.to_s} and #{@other.to_s})"
230
+ "(#{@val} and #{@other})"
221
231
  end
222
232
  end
223
233
 
@@ -236,18 +246,26 @@ module Spectre
236
246
  @@success = nil
237
247
 
238
248
  def expect desc
249
+ status = 'unknown'
250
+
239
251
  begin
240
- Logger.log_process("expect #{desc}")
252
+ Logging.log_process("expect #{desc}")
241
253
  yield
242
- Logger.log_status(desc, Logger::Status::OK)
254
+ Logging.log_status(desc, Logging::Status::OK)
255
+ status = 'ok'
243
256
  rescue Interrupt => e
257
+ status = 'skipped'
244
258
  raise e
245
259
  rescue AssertionFailure => e
246
- Logger.log_status(desc, Logger::Status::FAILED)
260
+ Logging.log_status(desc, Logging::Status::FAILED)
261
+ status = 'failed'
247
262
  raise AssertionFailure.new(e.message, e.expected, e.actual, desc), cause: nil
248
263
  rescue Exception => e
249
- Logger.log_status(desc, Logger::Status::ERROR)
264
+ Logging.log_status(desc, Logging::Status::ERROR)
265
+ status = 'error'
250
266
  raise AssertionFailure.new("An unexpected error occurred during expectation: #{e.message}", nil, nil, desc), cause: e
267
+ ensure
268
+ Spectre::Runner.current.expectations.append([desc, status])
251
269
  end
252
270
  end
253
271
 
@@ -256,7 +274,7 @@ module Spectre
256
274
  prefix += " '#{desc}'" if desc
257
275
 
258
276
  begin
259
- Logger.log_info(prefix) if desc
277
+ Logging.log_info(prefix) if desc
260
278
  yield
261
279
  @@success = true
262
280
  @@logger.info("#{prefix} finished with success")
@@ -281,7 +299,7 @@ module Spectre
281
299
  end
282
300
 
283
301
  Spectre.register do |config|
284
- @@logger = ::Logger.new(config['log_file'], progname: 'spectre/assertion')
302
+ @@logger = Spectre::Logging::ModuleLogger.new(config, 'spectre/assertion')
285
303
  @@debug = config['debug']
286
304
  end
287
305
 
@@ -0,0 +1,31 @@
1
+ require_relative '../spectre'
2
+
3
+ Thread.abort_on_exception = true
4
+
5
+ module Spectre
6
+ module Async
7
+ class << self
8
+ @@threads = {}
9
+
10
+ def async name='default', &block
11
+ unless @@threads.key? name
12
+ @@threads[name] = []
13
+ end
14
+
15
+ @@threads[name] << Thread.new(&block)
16
+ end
17
+
18
+ def await name='default'
19
+ return unless @@threads.key? name
20
+
21
+ threads = @@threads[name].map { |x| x.join() }
22
+
23
+ @@threads.delete(name)
24
+
25
+ threads.map { |x| x.value }
26
+ end
27
+ end
28
+
29
+ Spectre.delegate :async, :await, to: self
30
+ end
31
+ end
data/lib/spectre/bag.rb CHANGED
@@ -12,7 +12,7 @@ module Spectre
12
12
  end
13
13
  end
14
14
 
15
- Spectre.register do |config|
15
+ Spectre.register do |_config|
16
16
  @@bag = OpenStruct.new
17
17
  end
18
18
 
data/lib/spectre/curl.rb CHANGED
@@ -310,7 +310,7 @@ module Spectre::Curl
310
310
 
311
311
  start_time = Time.now
312
312
 
313
- stdin, stdout, stderr, wait_thr = Open3.popen3(sys_cmd)
313
+ _, stdout, stderr, wait_thr = Open3.popen3(sys_cmd)
314
314
 
315
315
  end_time = Time.now
316
316
 
@@ -359,8 +359,8 @@ module Spectre::Curl
359
359
  end
360
360
 
361
361
  res_log = "[<] #{req_id} #{res[:code]} #{res[:message]} (#{end_time - start_time}s)\n"
362
- res_headers.each do |header|
363
- res_log += "#{header[0].to_s.ljust(30, '.')}: #{header[1].to_s}\n"
362
+ res_headers.each do |http_header|
363
+ res_log += "#{http_header[0].to_s.ljust(30, '.')}: #{http_header[1].to_s}\n"
364
364
  end
365
365
 
366
366
  if res[:body] != nil and not res[:body].empty?
@@ -380,11 +380,9 @@ module Spectre::Curl
380
380
  Spectre.register do |config|
381
381
  @@debug = config['debug']
382
382
 
383
- @@logger = ::Logger.new(config['log_file'], progname: 'spectre/curl')
384
- @@logger.level = @@debug ? Logger::DEBUG : Logger::INFO
383
+ @@logger = Spectre::Logging::ModuleLogger.new(config, 'spectre/curl')
385
384
 
386
385
  @@secure_keys = config['secure_keys'] || []
387
-
388
386
  @@curl_path = config['curl_path'] || 'curl'
389
387
 
390
388
  if config.key? 'http'
@@ -119,6 +119,10 @@ class ::Hash
119
119
  end
120
120
 
121
121
  class ::Array
122
+ def first_element
123
+ self[0]
124
+ end
125
+
122
126
  def last_element
123
127
  self[-1]
124
128
  end
@@ -42,8 +42,6 @@ module Spectre::Http
42
42
  net_req['X-Auth-Token'] = token
43
43
  end
44
44
 
45
- private
46
-
47
45
  def self.authenticate keystone_url, username, password, project, domain, cert
48
46
  auth_data = {
49
47
  auth: {
data/lib/spectre/http.rb CHANGED
@@ -19,7 +19,7 @@ module Spectre
19
19
  'cert' => nil,
20
20
  'headers' => nil,
21
21
  'query' => nil,
22
- 'content_type' => '',
22
+ 'content_type' => nil,
23
23
  'timeout' => 180,
24
24
  'retries' => 0,
25
25
  }
@@ -27,9 +27,6 @@ module Spectre
27
27
  @@modules = []
28
28
 
29
29
  class HttpError < Exception
30
- def initialize message
31
- super message
32
- end
33
30
  end
34
31
 
35
32
  class SpectreHttpRequest < Spectre::DslClass
@@ -80,8 +77,7 @@ module Spectre
80
77
  data = data.to_h if data.is_a? OpenStruct
81
78
  body JSON.pretty_generate(data)
82
79
 
83
- # TODO: Only set content type, if not explicitly set
84
- content_type('application/json')
80
+ content_type('application/json') unless @__req['content_type']
85
81
  end
86
82
 
87
83
  def body body_content
@@ -112,6 +108,10 @@ module Spectre
112
108
  @__req['use_ssl'] = true
113
109
  end
114
110
 
111
+ def no_log!
112
+ @__req['no_log'] = true
113
+ end
114
+
115
115
  def to_s
116
116
  @__req.to_s
117
117
  end
@@ -314,7 +314,14 @@ module Spectre
314
314
 
315
315
  req_log = "[>] #{req_id} #{req['method']} #{uri}\n"
316
316
  req_log += header_to_s(net_req)
317
- req_log += try_format_json(req['body'], pretty: true) if req['body'] != nil and not req['body'].empty?
317
+
318
+ unless req['body'].nil? or req['body'].empty?
319
+ unless req['no_log']
320
+ req_log += try_format_json(req['body'], pretty: true)
321
+ else
322
+ req_log += '[...]'
323
+ end
324
+ end
318
325
 
319
326
  @@logger.info(req_log)
320
327
 
@@ -345,7 +352,14 @@ module Spectre
345
352
 
346
353
  res_log = "[<] #{req_id} #{net_res.code} #{net_res.message} (#{end_time - start_time}s)\n"
347
354
  res_log += header_to_s(net_res)
348
- res_log += try_format_json(net_res.body, pretty: true) unless net_res.body.nil? or net_res.body.empty?
355
+
356
+ unless net_res.body.nil? or net_res.body.empty?
357
+ unless req['no_log']
358
+ res_log += try_format_json(net_res.body, pretty: true)
359
+ else
360
+ res_log += '[...]'
361
+ end
362
+ end
349
363
 
350
364
  @@logger.info(res_log)
351
365
 
@@ -361,7 +375,7 @@ module Spectre
361
375
  end
362
376
 
363
377
  Spectre.register do |config|
364
- @@logger = ::Logger.new(config['log_file'], progname: 'spectre/http')
378
+ @@logger = Spectre::Logging::ModuleLogger.new(config, 'spectre/http')
365
379
  @@secure_keys = config['secure_keys'] || []
366
380
  @@debug = config['debug']
367
381
 
@@ -1,7 +1,7 @@
1
1
  require 'ectoplasm'
2
2
 
3
3
  module Spectre
4
- module Logger
4
+ module Logging
5
5
  class Console
6
6
  def initialize config
7
7
  raise 'No log format section in config for console logger' unless config.key? 'log_format' and config['log_format'].key? 'console'
@@ -1,5 +1,5 @@
1
1
  module Spectre
2
- module Logger
2
+ module Logging
3
3
  class File
4
4
  def initialize config
5
5
  raise 'No log format section in config for console logger' unless config.key? 'log_format' and config['log_format'].key? 'file'
@@ -9,77 +9,77 @@ module Spectre
9
9
  @fmt_end_group = @config['end_group']
10
10
  @fmt_sep = @config['separator']
11
11
 
12
- @file_log = ::Logger.new config['log_file'], progname: 'spectre'
12
+ @file_log = ::Logger.new(config['log_file'], progname: 'spectre')
13
13
  @file_log.level = config['debug'] ? 'DEBUG' : 'INFO'
14
14
  end
15
15
 
16
16
  def start_subject subject
17
- @file_log.debug "start running subject '#{subject.desc}'"
17
+ @file_log.debug("start running subject '#{subject.desc}'")
18
18
  end
19
19
 
20
20
  def end_subject subject
21
- @file_log.debug "subject '#{subject.desc}' finished"
21
+ @file_log.debug("subject '#{subject.desc}' finished")
22
22
  end
23
23
 
24
24
  def start_context context
25
25
  if context and context.__desc
26
- @file_log.debug "start running context '#{context.__desc}'"
26
+ @file_log.debug("start running context '#{context.__desc}'")
27
27
  else
28
- @file_log.debug "start running main context of #{context.__subject.desc}"
28
+ @file_log.debug("start running main context of #{context.__subject.desc}")
29
29
  end
30
30
  end
31
31
 
32
32
  def end_context context
33
33
  if context and context.__desc
34
- @file_log.debug "context '#{context.__desc}' finished"
34
+ @file_log.debug("context '#{context.__desc}' finished")
35
35
  else
36
- @file_log.debug "main context finished of #{context.__subject.desc}"
36
+ @file_log.debug("main context finished of #{context.__subject.desc}")
37
37
  end
38
38
  end
39
39
 
40
40
  def start_spec spec, data=nil
41
41
  log_msg = "start running spec [#{spec.name}] '#{spec.desc}'"
42
42
  log_msg += " with data #{data}" if data
43
- @file_log.debug log_msg
43
+ @file_log.debug(log_msg)
44
44
  end
45
45
 
46
46
  def end_spec spec, data=nil
47
47
  log_msg = "running spec [#{spec.name}] '#{spec.desc}'"
48
48
  log_msg += " with data #{data}" if data
49
49
  log_msg += " finished"
50
- @file_log.debug log_msg
50
+ @file_log.debug(log_msg)
51
51
  end
52
52
 
53
53
  def log_separator desc
54
54
  desc = @fmt_sep.gsub('<desc>', desc) if @fmt_sep
55
- @file_log.info desc
55
+ @file_log.info(desc)
56
56
  end
57
57
 
58
58
  def start_group desc
59
59
  desc = @fmt_start_group.gsub('<desc>', desc) if @fmt_start_group
60
- @file_log.info desc
60
+ @file_log.info(desc)
61
61
  end
62
62
 
63
63
  def end_group desc
64
64
  desc = @fmt_end_group.gsub('<desc>', desc) if @fmt_end_group
65
- @file_log.info desc
65
+ @file_log.info(desc)
66
66
  end
67
67
 
68
68
  def log_process desc
69
- @file_log.debug desc
69
+ @file_log.debug(desc)
70
70
  end
71
71
 
72
72
  def log_info message
73
- @file_log.info "#{Status::INFO} #{message}"
73
+ @file_log.info("#{Status::INFO} #{message}")
74
74
  end
75
75
 
76
76
  def log_debug message
77
- @file_log.debug "#{Status::DEBUG} #{message}"
77
+ @file_log.debug("#{Status::DEBUG} #{message}")
78
78
  end
79
79
 
80
80
  def log_error spec, exception
81
81
  file, line = exception.backtrace[0].match(/(.*\.rb):(\d+)/).captures
82
- @file_log.error "An unexpected error occurred at '#{file}:#{line}' while running spec '#{spec.name}': [#{exception.class}] #{exception.message}\n#{exception.backtrace.join "\n"}"
82
+ @file_log.error("An unexpected error occurred at '#{file}:#{line}' while running spec '#{spec.name}': [#{exception.class}] #{exception.message}\n#{exception.backtrace.join "\n"}")
83
83
  end
84
84
 
85
85
  def log_skipped spec, message=nil
@@ -89,13 +89,13 @@ module Spectre
89
89
  txt += ': ' + message
90
90
  end
91
91
 
92
- @file_log.warn txt
92
+ @file_log.warn(txt)
93
93
  end
94
94
 
95
95
  def log_status desc, status, annotation=nil
96
96
  msg = "expected #{desc}...#{status.upcase}"
97
97
  msg += " - #{annotation}" if annotation
98
- @file_log.debug msg
98
+ @file_log.debug(msg)
99
99
  end
100
100
  end
101
101
  end