spectre-core 1.9.0 → 1.12.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.
- checksums.yaml +4 -4
- data/exe/spectre +51 -46
- data/lib/spectre/assertion.rb +50 -37
- data/lib/spectre/bag.rb +4 -2
- data/lib/spectre/curl.rb +62 -33
- data/lib/spectre/diagnostic.rb +12 -2
- data/lib/spectre/environment.rb +9 -5
- data/lib/spectre/helpers.rb +81 -22
- data/lib/spectre/http/basic_auth.rb +5 -2
- data/lib/spectre/http/keystone.rb +76 -73
- data/lib/spectre/http.rb +373 -359
- data/lib/spectre/logger/console.rb +7 -6
- data/lib/spectre/logger/file.rb +96 -96
- data/lib/spectre/logger.rb +146 -144
- data/lib/spectre/mixin.rb +35 -18
- data/lib/spectre/reporter/console.rb +3 -5
- data/lib/spectre/reporter/junit.rb +5 -3
- data/lib/spectre/resources.rb +7 -4
- data/lib/spectre.rb +58 -45
- metadata +26 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77d4435f515a88fa60eef0a6c43b90975fb6ae1168a60294ee2847536ff51a67
|
4
|
+
data.tar.gz: 1366a0d67961a565bf2020d9fa9e6724f5df4b4add1ac58712ed2cdfe992e74d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7699c3e1433edc8b7b0c7886f28ef90ad3f6438b2189ebbbe8bfc40c6386f7b142bd8848809af13e9c893d8efcffc6598c595fea8bdea9ff67899a84c5394e27
|
7
|
+
data.tar.gz: 1b5da1f3b490dbcf2510e8a58306efe3a0924891c5004fe9862854f0700e502d81b46e8353e85b77be43f4c4aea9e67b7c4db276501f971046d47e4488c5d07f
|
data/exe/spectre
CHANGED
@@ -10,14 +10,6 @@ require 'ectoplasm'
|
|
10
10
|
require_relative '../lib/spectre'
|
11
11
|
|
12
12
|
|
13
|
-
class ::Hash
|
14
|
-
def deep_merge!(second)
|
15
|
-
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge!(v2, &merger) : v2 }
|
16
|
-
self.merge!(second, &merger)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
13
|
DEFAULT_CONFIG = {
|
22
14
|
'config_file' => './spectre.yml',
|
23
15
|
'environment' => 'default',
|
@@ -44,7 +36,7 @@ DEFAULT_CONFIG = {
|
|
44
36
|
'separator' => '-- <desc>',
|
45
37
|
'start_group' => "-- Start '<desc>'",
|
46
38
|
'end_group' => "-- End '<desc>'",
|
47
|
-
}
|
39
|
+
},
|
48
40
|
},
|
49
41
|
'debug' => false,
|
50
42
|
'out_path' => './reports',
|
@@ -75,7 +67,7 @@ DEFAULT_CONFIG = {
|
|
75
67
|
],
|
76
68
|
'exclude' => [
|
77
69
|
|
78
|
-
]
|
70
|
+
],
|
79
71
|
}
|
80
72
|
|
81
73
|
|
@@ -148,10 +140,9 @@ Specific options:}
|
|
148
140
|
|
149
141
|
curr_opt = cmd_options
|
150
142
|
(key.split '.').each do |k|
|
151
|
-
curr_opt[k] = {}
|
143
|
+
curr_opt[k] = {} unless curr_opt.key? k
|
152
144
|
end
|
153
145
|
curr_opt = val
|
154
|
-
|
155
146
|
end
|
156
147
|
|
157
148
|
opts.separator "\nCommon options:"
|
@@ -226,7 +217,7 @@ cfg['env_partial_patterns'].each do |pattern|
|
|
226
217
|
Dir.glob(pattern).each do|f|
|
227
218
|
partial_env = YAML.load_file(f)
|
228
219
|
name = partial_env.delete('name') || 'default'
|
229
|
-
next
|
220
|
+
next unless envs.key? name
|
230
221
|
|
231
222
|
envs[name].deep_merge! partial_env
|
232
223
|
end
|
@@ -238,6 +229,10 @@ cfg.merge! env if env
|
|
238
229
|
|
239
230
|
String.colored! if cfg['colored']
|
240
231
|
|
232
|
+
# Load environment exlicitly before loading specs to make it available in spec definition
|
233
|
+
require_relative '../lib/spectre/environment' unless cfg['exclude'].include? 'spectre/environment'
|
234
|
+
Spectre.configure(cfg)
|
235
|
+
|
241
236
|
|
242
237
|
###########################################
|
243
238
|
# Load Specs
|
@@ -256,11 +251,11 @@ end
|
|
256
251
|
###########################################
|
257
252
|
|
258
253
|
|
259
|
-
if
|
254
|
+
if 'list' == action
|
260
255
|
colors = [:blue, :magenta, :yellow, :green]
|
261
256
|
specs = Spectre.specs(cfg['specs'], cfg['tags'])
|
262
257
|
|
263
|
-
exit 1
|
258
|
+
exit 1 unless specs.any?
|
264
259
|
|
265
260
|
counter = 0
|
266
261
|
|
@@ -285,42 +280,52 @@ end
|
|
285
280
|
###########################################
|
286
281
|
|
287
282
|
|
288
|
-
if
|
283
|
+
if 'run' == action
|
289
284
|
# Initialize logger
|
290
285
|
now = Time.now
|
291
286
|
|
292
|
-
cfg['log_file'] = cfg['log_file'].frmt(
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
287
|
+
cfg['log_file'] = cfg['log_file'].frmt(
|
288
|
+
{
|
289
|
+
shortdate: now.strftime('%Y-%m-%d'),
|
290
|
+
date: now.strftime('%Y-%m-%d_%H%M%S'),
|
291
|
+
timestamp: now.strftime('%s'),
|
292
|
+
subject: 'spectre',
|
293
|
+
})
|
298
294
|
|
299
295
|
log_dir = File.dirname cfg['log_file']
|
300
|
-
FileUtils.makedirs log_dir
|
296
|
+
FileUtils.makedirs log_dir unless Dir.exists? log_dir
|
301
297
|
|
302
298
|
# Load Modules
|
299
|
+
|
303
300
|
cfg['modules']
|
304
301
|
.concat(cfg['include'])
|
305
302
|
.select { |mod| !cfg['exclude'].include? mod }
|
306
303
|
.each do |mod|
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
if File.exists? mod
|
311
|
-
require_relative mod
|
304
|
+
begin
|
305
|
+
mod_file = mod + '.rb'
|
306
|
+
spectre_lib_mod = File.join(File.dirname(__dir__), 'lib', mod_file)
|
312
307
|
|
313
|
-
|
314
|
-
|
308
|
+
if File.exists? mod_file
|
309
|
+
require_relative mod_file
|
315
310
|
|
316
|
-
|
317
|
-
|
318
|
-
end
|
311
|
+
elsif File.exists? spectre_lib_mod
|
312
|
+
require_relative spectre_lib_mod
|
319
313
|
|
320
|
-
|
321
|
-
|
322
|
-
exit 1
|
314
|
+
else
|
315
|
+
require mod
|
323
316
|
end
|
317
|
+
rescue LoadError => e
|
318
|
+
puts "Unable to load module #{mod}. Check if the module exists or remove it from your spectre config:\n#{e.message}"
|
319
|
+
exit 1
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
# Load mixins
|
324
|
+
|
325
|
+
cfg['mixin_patterns'].each do |pattern|
|
326
|
+
Dir.glob(pattern).each do|f|
|
327
|
+
require_relative File.join(Dir.pwd, f)
|
328
|
+
end
|
324
329
|
end
|
325
330
|
|
326
331
|
Spectre.configure(cfg)
|
@@ -334,7 +339,7 @@ if action == 'run'
|
|
334
339
|
|
335
340
|
specs = Spectre.specs(cfg['specs'], cfg['tags'])
|
336
341
|
|
337
|
-
|
342
|
+
unless specs.any?
|
338
343
|
puts "No specs found in #{Dir.pwd}"
|
339
344
|
exit 1
|
340
345
|
end
|
@@ -346,9 +351,9 @@ if action == 'run'
|
|
346
351
|
reporter.report(run_infos)
|
347
352
|
end
|
348
353
|
|
349
|
-
errors = run_infos.select { |x| x.error
|
354
|
+
errors = run_infos.select { |x| nil != x.error or nil != x.failure }
|
350
355
|
|
351
|
-
exit 0 if cfg['ignore_failure'] or errors.
|
356
|
+
exit 0 if cfg['ignore_failure'] or not errors.any?
|
352
357
|
|
353
358
|
exit 1
|
354
359
|
end
|
@@ -359,8 +364,8 @@ end
|
|
359
364
|
###########################################
|
360
365
|
|
361
366
|
|
362
|
-
if
|
363
|
-
exit 1
|
367
|
+
if 'envs' == action
|
368
|
+
exit 1 unless envs.any?
|
364
369
|
puts envs.pretty
|
365
370
|
exit 0
|
366
371
|
end
|
@@ -371,7 +376,7 @@ end
|
|
371
376
|
###########################################
|
372
377
|
|
373
378
|
|
374
|
-
if
|
379
|
+
if 'show' == action
|
375
380
|
puts cfg.pretty
|
376
381
|
exit 0
|
377
382
|
end
|
@@ -382,7 +387,7 @@ end
|
|
382
387
|
###########################################
|
383
388
|
|
384
389
|
|
385
|
-
if
|
390
|
+
if 'dump' == action
|
386
391
|
puts YAML.dump(cfg)
|
387
392
|
end
|
388
393
|
|
@@ -487,7 +492,7 @@ gem 'spectre-core', '>= #{Spectre::VERSION}'
|
|
487
492
|
# gem 'spectre-git', '>= 0.1.0'
|
488
493
|
]
|
489
494
|
|
490
|
-
if
|
495
|
+
if 'init' == action
|
491
496
|
DEFAULT_FILES = [
|
492
497
|
['./environments/default.env.yml', DEFAULT_ENV_CFG],
|
493
498
|
['./environments/default.env.secret.yml', DEFAULT_ENV_SECRET_CFG],
|
@@ -502,10 +507,10 @@ if action == 'init'
|
|
502
507
|
end
|
503
508
|
|
504
509
|
DEFAULT_FILES.each do |file, content|
|
505
|
-
|
510
|
+
unless File.exists? file
|
506
511
|
File.write(file, content)
|
507
512
|
end
|
508
513
|
end
|
509
514
|
|
510
515
|
exit 0
|
511
|
-
end
|
516
|
+
end
|
data/lib/spectre/assertion.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative '../spectre'
|
2
|
+
|
1
3
|
require 'ostruct'
|
2
4
|
require_relative 'logger'
|
3
5
|
|
@@ -6,23 +8,23 @@ module Spectre
|
|
6
8
|
module Assertion
|
7
9
|
class ::Object
|
8
10
|
def should_be(val)
|
9
|
-
|
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
|
10
12
|
end
|
11
13
|
|
12
14
|
def should_be_empty
|
13
|
-
raise AssertionFailure.new("The value '#{self.to_s.trim}' should be empty", nil, self) unless self
|
15
|
+
raise AssertionFailure.new("The value '#{self.to_s.trim}' should be empty", nil, self) unless self.nil?
|
14
16
|
end
|
15
17
|
|
16
18
|
def should_not_be(val)
|
17
|
-
|
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
|
18
20
|
end
|
19
21
|
|
20
22
|
def should_not_exist
|
21
|
-
|
23
|
+
raise AssertionFailure.new("The value '#{self.to_s.trim}' should not exist, but it does", val, self) unless self.to_s != nil
|
22
24
|
end
|
23
25
|
|
24
26
|
def should_not_be_empty
|
25
|
-
raise AssertionFailure.new('The value
|
27
|
+
raise AssertionFailure.new('The value is empty', 'nothing', self) unless self != nil
|
26
28
|
end
|
27
29
|
|
28
30
|
def or other
|
@@ -34,7 +36,6 @@ module Spectre
|
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
37
|
-
|
38
39
|
class ::NilClass
|
39
40
|
def should_be(val)
|
40
41
|
raise AssertionFailure.new("There is nothing, but the value should be '#{val.to_s.trim}'", val, nil) unless val == nil
|
@@ -51,11 +52,10 @@ module Spectre
|
|
51
52
|
end
|
52
53
|
|
53
54
|
def should_not_be_empty
|
54
|
-
raise AssertionFailure.new('
|
55
|
+
raise AssertionFailure.new('The list is empty', 'nil')
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
58
|
-
|
59
59
|
class ::Hash
|
60
60
|
def should_contain(other)
|
61
61
|
raise AssertionFailure.new(other, self) unless self.merge(other) == self
|
@@ -64,8 +64,25 @@ module Spectre
|
|
64
64
|
def should_not_contain(other)
|
65
65
|
raise AssertionFailure.new(other, self) unless self.merge(other) != self
|
66
66
|
end
|
67
|
+
|
68
|
+
def should_be_empty
|
69
|
+
raise AssertionFailure.new('The object should be empty', nil, self) unless self.empty?
|
70
|
+
end
|
71
|
+
|
72
|
+
def should_not_be_empty
|
73
|
+
raise AssertionFailure.new('The object should not be empty', nil, self) if self.empty?
|
74
|
+
end
|
67
75
|
end
|
68
76
|
|
77
|
+
class ::OpenStruct
|
78
|
+
def should_be_empty
|
79
|
+
raise AssertionFailure.new('The object should be empty', nil, self) unless self.to_h.empty?
|
80
|
+
end
|
81
|
+
|
82
|
+
def should_not_be_empty
|
83
|
+
raise AssertionFailure.new('The object should not be empty', nil, self) if self.to_h.empty?
|
84
|
+
end
|
85
|
+
end
|
69
86
|
|
70
87
|
class ::Array
|
71
88
|
def should_contain(val)
|
@@ -76,7 +93,7 @@ module Spectre
|
|
76
93
|
val = OpenStruct.new(val)
|
77
94
|
end
|
78
95
|
|
79
|
-
raise AssertionFailure.new("The list [#{list.join(', ').trim}] should contain '#{val.trim}'", val, list) unless list.include? val
|
96
|
+
raise AssertionFailure.new("The list [#{list.join(', ').trim}] should contain '#{val.to_s.trim}'", val, list) unless list.include? val
|
80
97
|
end
|
81
98
|
|
82
99
|
def should_not_contain(val)
|
@@ -87,19 +104,18 @@ module Spectre
|
|
87
104
|
val = OpenStruct.new(val)
|
88
105
|
end
|
89
106
|
|
90
|
-
raise AssertionFailure.new("The list [#{list.join(', ').trim}] should not contain '#{val.trim}'", val, list) if list.include? val
|
107
|
+
raise AssertionFailure.new("The list [#{list.join(', ').trim}] should not contain '#{val.to_s.trim}'", val, list) if list.include? val
|
91
108
|
end
|
92
109
|
|
93
110
|
def should_be_empty
|
94
|
-
raise AssertionFailure.new('
|
111
|
+
raise AssertionFailure.new('The list is not empty', self) unless self.empty?
|
95
112
|
end
|
96
113
|
|
97
114
|
def should_not_be_empty
|
98
|
-
raise AssertionFailure.new('
|
115
|
+
raise AssertionFailure.new('The list is empty', self) if self.empty?
|
99
116
|
end
|
100
117
|
end
|
101
118
|
|
102
|
-
|
103
119
|
class ::String
|
104
120
|
def should_be(val)
|
105
121
|
raise AssertionFailure.new("The text '#{self.trim}' should be '#{val.to_s.trim}'", val, self) unless self == val
|
@@ -110,7 +126,7 @@ module Spectre
|
|
110
126
|
end
|
111
127
|
|
112
128
|
def should_not_be(val)
|
113
|
-
|
129
|
+
raise AssertionFailure.new("The text '#{self.trim}' should not be '#{val.to_s.trim}'", val, self) unless self != val
|
114
130
|
end
|
115
131
|
|
116
132
|
def should_not_be_empty
|
@@ -118,8 +134,10 @@ module Spectre
|
|
118
134
|
end
|
119
135
|
|
120
136
|
def should_contain(value)
|
137
|
+
raise AssertionFailure.new("The value is nil") if value.nil?
|
138
|
+
|
121
139
|
predicate = proc { |x| self.include? x.to_s }
|
122
|
-
evaluation = SingleEvaluation.new
|
140
|
+
evaluation = SingleEvaluation.new(value)
|
123
141
|
success = evaluation.call(predicate)
|
124
142
|
|
125
143
|
return if success
|
@@ -143,7 +161,6 @@ module Spectre
|
|
143
161
|
alias :& :and
|
144
162
|
end
|
145
163
|
|
146
|
-
|
147
164
|
class Evaluation
|
148
165
|
def initialize value, other
|
149
166
|
@value = value
|
@@ -162,10 +179,9 @@ module Spectre
|
|
162
179
|
alias :& :and
|
163
180
|
end
|
164
181
|
|
165
|
-
|
166
182
|
class SingleEvaluation < Evaluation
|
167
183
|
def initialize value
|
168
|
-
super
|
184
|
+
super(value, nil)
|
169
185
|
end
|
170
186
|
|
171
187
|
def call predicate
|
@@ -177,10 +193,9 @@ module Spectre
|
|
177
193
|
end
|
178
194
|
end
|
179
195
|
|
180
|
-
|
181
196
|
class OrEvaluation < Evaluation
|
182
197
|
def initialize value, other
|
183
|
-
super
|
198
|
+
super(value, other)
|
184
199
|
end
|
185
200
|
|
186
201
|
def call predicate
|
@@ -192,10 +207,9 @@ module Spectre
|
|
192
207
|
end
|
193
208
|
end
|
194
209
|
|
195
|
-
|
196
210
|
class AndEvaluation < Evaluation
|
197
211
|
def initialize value, other
|
198
|
-
super
|
212
|
+
super(value, other)
|
199
213
|
end
|
200
214
|
|
201
215
|
def call predicate
|
@@ -207,7 +221,6 @@ module Spectre
|
|
207
221
|
end
|
208
222
|
end
|
209
223
|
|
210
|
-
|
211
224
|
class AssertionFailure < ExpectationFailure
|
212
225
|
attr_reader :expected, :actual
|
213
226
|
|
@@ -222,27 +235,16 @@ module Spectre
|
|
222
235
|
class << self
|
223
236
|
@@success = nil
|
224
237
|
|
225
|
-
def eval_assertion predicate, val
|
226
|
-
if val.is_a? Proc
|
227
|
-
val.call(predicate)
|
228
|
-
else
|
229
|
-
predicate.call(val)
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
238
|
def expect desc
|
234
239
|
begin
|
235
240
|
Logger.log_process("expect #{desc}")
|
236
241
|
yield
|
237
242
|
Logger.log_status(desc, Logger::Status::OK)
|
238
|
-
|
239
243
|
rescue Interrupt => e
|
240
244
|
raise e
|
241
|
-
|
242
245
|
rescue AssertionFailure => e
|
243
246
|
Logger.log_status(desc, Logger::Status::FAILED)
|
244
247
|
raise AssertionFailure.new(e.message, e.expected, e.actual, desc), cause: nil
|
245
|
-
|
246
248
|
rescue Exception => e
|
247
249
|
Logger.log_status(desc, Logger::Status::ERROR)
|
248
250
|
raise AssertionFailure.new("An unexpected error occured during expectation: #{e.message}", nil, nil, desc), cause: e
|
@@ -250,15 +252,21 @@ module Spectre
|
|
250
252
|
end
|
251
253
|
|
252
254
|
def observe desc = nil
|
255
|
+
prefix = 'observing'
|
256
|
+
prefix += " '#{desc}'" if desc
|
257
|
+
|
253
258
|
begin
|
254
|
-
Logger.log_info(
|
259
|
+
Logger.log_info(prefix) if desc
|
255
260
|
yield
|
256
261
|
@@success = true
|
257
|
-
|
262
|
+
@@logger.info("#{prefix} finished with success")
|
258
263
|
rescue Interrupt => e
|
259
264
|
raise e
|
260
|
-
|
261
265
|
rescue Exception => e
|
266
|
+
error_message = "#{prefix} finished with failure: #{e.message}"
|
267
|
+
error_message += "\n" + e.backtrace.join("\n") if @@debug
|
268
|
+
|
269
|
+
@@logger.info(error_message)
|
262
270
|
@@success = false
|
263
271
|
end
|
264
272
|
end
|
@@ -272,6 +280,11 @@ module Spectre
|
|
272
280
|
end
|
273
281
|
end
|
274
282
|
|
283
|
+
Spectre.register do |config|
|
284
|
+
@@logger = ::Logger.new(config['log_file'], progname: 'spectre/assertion')
|
285
|
+
@@debug = config['debug']
|
286
|
+
end
|
287
|
+
|
275
288
|
Spectre.delegate :expect, :observe, :success?, :fail_with, to: self
|
276
289
|
end
|
277
290
|
end
|
data/lib/spectre/bag.rb
CHANGED