spectre-core 1.9.0 → 1.12.1
Sign up to get free protection for your applications and to get access to all the features.
- 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