spectre-core 1.8.4 → 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.
data/exe/spectre CHANGED
@@ -1,494 +1,516 @@
1
- #! /usr/bin/ruby
2
- # frozen_string_literal: true
3
-
4
- require 'yaml'
5
- require 'ostruct'
6
- require 'optparse'
7
- require 'fileutils'
8
- require 'ectoplasm'
9
-
10
- require_relative '../lib/spectre'
11
-
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
- DEFAULT_CONFIG = {
22
- 'config_file' => './spectre.yml',
23
- 'environment' => 'default',
24
- 'specs' => [],
25
- 'tags' => [],
26
- 'colored' => true,
27
- 'verbose' => false,
28
- 'reporters' => [
29
- 'Spectre::Reporter::Console',
30
- ],
31
- 'loggers' => [
32
- 'Spectre::Logger::Console',
33
- 'Spectre::Logger::File',
34
- ],
35
- 'log_file' => './logs/spectre_<date>.log',
36
- 'log_format' => {
37
- 'console' => {
38
- 'indent' => 2,
39
- 'width' => 80,
40
- 'end_context' => nil,
41
- 'separator' => '<indent><desc>',
42
- },
43
- 'file' => {
44
- 'separator' => '-- <desc>',
45
- 'start_group' => "-- Start '<desc>'",
46
- 'end_group' => "-- End '<desc>'",
47
- }
48
- },
49
- 'debug' => false,
50
- 'out_path' => './reports',
51
- 'spec_patterns' => ['./specs/**/*.spec.rb'],
52
- 'mixin_patterns' => ['../common/mixins/**/*.mixin.rb', './mixins/**/*.mixin.rb'],
53
- 'env_patterns' => ['./environments/**/*.env.yml'],
54
- 'env_partial_patterns' => ['./environments/**/*.env.secret.yml'],
55
- 'resource_paths' => ['../common/resources', './resources'],
56
- 'modules' => [
57
- 'spectre/helpers',
58
- 'spectre/reporter/console',
59
- 'spectre/reporter/junit',
60
- 'spectre/logger/console',
61
- 'spectre/logger/file',
62
- 'spectre/assertion',
63
- 'spectre/diagnostic',
64
- 'spectre/environment',
65
- 'spectre/mixin',
66
- 'spectre/bag',
67
- 'spectre/http',
68
- 'spectre/http/basic_auth',
69
- 'spectre/http/keystone',
70
- 'spectre/resources',
71
- 'spectre/ssh',
72
- 'spectre/ftp',
73
- 'spectre/mysql',
74
- # 'spectre/postgres',
75
- ],
76
- 'include' => [
77
-
78
- ],
79
- 'exclude' => [
80
-
81
- ]
82
- }
83
-
84
-
85
- cmd_options = {}
86
-
87
- opt_parser = OptionParser.new do |opts|
88
- opts.banner = %{Spectre #{Spectre::VERSION}
89
-
90
- Usage: spectre [command] [options]
91
-
92
- Commands:
93
- list List specs
94
- run Run specs (default)
95
- show Print current environment settings
96
- dump Dumps the given environment in YAML format to console
97
- init Initializes a new spectre project
98
-
99
- Specific options:}
100
-
101
- opts.on('-s SPEC,SPEC', '--specs SPEC,SPEC', Array, 'The specs to run') do |specs|
102
- cmd_options['specs'] = specs
103
- end
104
-
105
- opts.on('-t TAG,TAG', '--tags TAG,TAG', Array, 'Run only specs with given tags') do |tags|
106
- cmd_options['tags'] = tags
107
- end
108
-
109
- opts.on('-e NAME', '--env NAME', 'Name of the environment to load') do |env_name|
110
- cmd_options['environment'] = env_name
111
- end
112
-
113
- opts.on('-c FILE', '--config FILE', 'Config file to load') do |file_path|
114
- cmd_options['config_file'] = file_path
115
- end
116
-
117
- opts.on('--spec-pattern PATTERN', Array, 'File pattern for spec files') do |spec_pattern|
118
- cmd_options['spec_patterns'] = spec_pattern
119
- end
120
-
121
- opts.on('--env-pattern PATTERN', Array, 'File pattern for environment files') do |env_patterns|
122
- cmd_options['env_patterns'] = env_patterns
123
- end
124
-
125
- opts.on('--no-color', 'Disable colored output') do
126
- cmd_options['colored'] = false
127
- end
128
-
129
- opts.on('-o PATH', '--out PATH', 'Output directory path') do |path|
130
- cmd_options['out_path'] = path
131
- end
132
-
133
- opts.on('-r NAME', '--reporter NAME', Array, "A list of reporters to use") do |reporters|
134
- cmd_options['reporters'] = reporters
135
- end
136
-
137
- opts.on('-d', '--debug', "Run in debug mode") do
138
- cmd_options['debug'] = true
139
- end
140
-
141
- opts.on('-p KEY=VAL', '--property KEY=VAL', "Override config option. Use `spectre show` to get list of available options") do |option|
142
- key, val = option.split '='
143
- val = val.split ',' if DEFAULT_CONFIG[key].is_a? Array
144
- val = ['true', '1'].include? val if [true, false].include? DEFAULT_CONFIG[key]
145
- val = val.to_i if DEFAULT_CONFIG[key].is_a? Integer
146
- cmd_options[key] = val
147
-
148
- curr_opt = cmd_options
149
- (key.split '.').each do |k|
150
- curr_opt[k] = {} if not curr_opt.key? k
151
- end
152
- curr_opt = val
153
-
154
- end
155
-
156
- opts.separator "\nCommon options:"
157
-
158
- opts.on_tail('--version', 'Print current installed version') do
159
- puts Spectre::VERSION
160
- exit
161
- end
162
-
163
- opts.on_tail('-h', '--help', 'Print this help') do
164
- puts opts
165
- exit
166
- end
167
- end.parse!
168
-
169
-
170
- action = ARGV[0] || 'run'
171
-
172
-
173
- ###########################################
174
- # Load Config
175
- ###########################################
176
-
177
-
178
- cfg = {}
179
- cfg.deep_merge! DEFAULT_CONFIG
180
-
181
- global_config_file = File.join File.expand_path('~'), '.spectre'
182
-
183
- if File.exists? global_config_file
184
- global_options = YAML.load_file(global_config_file)
185
- cfg.deep_merge! global_options if global_options
186
- end
187
-
188
- config_file = cmd_options['config_file'] || cfg['config_file']
189
-
190
- if File.exists? config_file
191
- file_options = YAML.load_file(config_file)
192
- cfg.deep_merge! file_options
193
- Dir.chdir File.dirname(config_file)
194
- end
195
-
196
- cfg.deep_merge! cmd_options
197
-
198
-
199
- ###########################################
200
- # Load Environment
201
- ###########################################
202
-
203
-
204
- envs = {}
205
- read_env_files = {}
206
- cfg['env_patterns'].each do |pattern|
207
- Dir.glob(pattern).each do|f|
208
- spec_env = YAML.load_file(f)
209
- name = spec_env.delete('name') || 'default'
210
-
211
- if envs.key? name
212
- existing_env_file = read_env_files[name]
213
- puts "Duplicate environment definition detected with name #{name} in '#{f}'. Previously defined in '#{existing_env_file}'"
214
- exit 1
215
- end
216
-
217
- read_env_files[name] = f
218
- envs[name] = spec_env
219
- end
220
- end
221
-
222
- # Merge partial environment configs with existing environments
223
- cfg['env_partial_patterns'].each do |pattern|
224
- Dir.glob(pattern).each do|f|
225
- partial_env = YAML.load_file(f)
226
- name = partial_env.delete('name') || 'default'
227
- next if not envs.key? name
228
-
229
- envs[name].deep_merge! partial_env
230
- end
231
- end
232
-
233
- env = envs[cfg['environment']]
234
- cfg.merge! env if env
235
-
236
-
237
- String.colored! if cfg['colored']
238
-
239
-
240
- ###########################################
241
- # Load Specs
242
- ###########################################
243
-
244
-
245
- cfg['spec_patterns'].each do |pattern|
246
- Dir.glob(pattern).each do|f|
247
- require_relative File.join(Dir.pwd, f)
248
- end
249
- end
250
-
251
-
252
- ###########################################
253
- # List specs
254
- ###########################################
255
-
256
-
257
- if action == 'list'
258
- colors = [:blue, :magenta, :yellow, :green]
259
- specs = Spectre.specs(cfg['specs'], cfg['tags'])
260
-
261
- exit 1 if specs.length == 0
262
-
263
- counter = 0
264
-
265
- specs.group_by { |x| x.subject }.each do |subject, spec_group|
266
- spec_group.each do |spec|
267
- tags = spec.tags.map { |x| '#' + x.to_s }.join ' '
268
- desc = subject.desc
269
- desc += ' - ' + spec.context.__desc + ' -' if spec.context.__desc
270
- desc += ' ' + spec.desc
271
- puts "[#{spec.name}]".send(colors[counter % colors.length]) + " #{desc} #{tags.cyan}"
272
- end
273
-
274
- counter += 1
275
- end
276
-
277
- exit 0
278
- end
279
-
280
-
281
- ###########################################
282
- # Run
283
- ###########################################
284
-
285
-
286
- if action == 'run'
287
- # Initialize logger
288
- now = Time.now
289
-
290
- cfg['log_file'] = cfg['log_file'].frmt({
291
- shortdate: now.strftime('%Y-%m-%d'),
292
- date: now.strftime('%Y-%m-%d_%H%M%S'),
293
- timestamp: now.strftime('%s'),
294
- subject: 'spectre',
295
- })
296
-
297
- log_dir = File.dirname cfg['log_file']
298
- FileUtils.makedirs log_dir if !Dir.exists? log_dir
299
-
300
- # Load Modules
301
- cfg['modules']
302
- .concat(cfg['include'])
303
- .select { |mod| !cfg['exclude'].include? mod }
304
- .each do |mod|
305
- begin
306
- spectre_lib_mod = File.join('../lib', mod)
307
-
308
- if File.exists? mod
309
- require_relative mod
310
-
311
- elsif File.exists? spectre_lib_mod
312
- require_relative spectre_lib_mod
313
-
314
- else
315
- require mod
316
- end
317
-
318
- rescue LoadError => e
319
- puts "Unable to load module #{mod}. Check if the module exists or remove it from your spectre config:\n#{e.message}"
320
- exit 1
321
- end
322
- end
323
-
324
- Spectre.configure(cfg)
325
-
326
- Spectre::Logger.debug! if cfg['debug']
327
-
328
- cfg['loggers'].each do |logger_name|
329
- logger = Kernel.const_get(logger_name).new(cfg)
330
- Spectre::Logger.add(logger)
331
- end if cfg['loggers']
332
-
333
- specs = Spectre.specs(cfg['specs'], cfg['tags'])
334
-
335
- if specs.length == 0
336
- puts "No specs found in #{Dir.pwd}"
337
- exit 1
338
- end
339
-
340
- run_infos = Spectre::Runner.new.run(specs)
341
-
342
- cfg['reporters'].each do |reporter|
343
- reporter = Kernel.const_get(reporter).new(cfg)
344
- reporter.report(run_infos)
345
- end
346
-
347
- exit 0
348
- end
349
-
350
-
351
- ###########################################
352
- # Envs
353
- ###########################################
354
-
355
-
356
- if action == 'envs'
357
- exit 1 if envs.length == 0
358
- puts envs.pretty
359
- exit 0
360
- end
361
-
362
-
363
- ###########################################
364
- # Show
365
- ###########################################
366
-
367
-
368
- if action == 'show'
369
- puts cfg.pretty
370
- exit 0
371
- end
372
-
373
-
374
- ###########################################
375
- # Dump
376
- ###########################################
377
-
378
-
379
- if action == 'dump'
380
- puts YAML.dump(cfg)
381
- end
382
-
383
-
384
- ###########################################
385
- # Init
386
- ###########################################
387
-
388
- DEFAULT_SPECTRE_CFG = %{log_file: ./logs/spectre_<date>.log
389
- env_patterns:
390
- - './environments/**/*.env.yml'
391
- env_partial_patterns:
392
- - './environments/**/*.env.secret.yml'
393
- spec_patterns:
394
- - './specs/**/*.spec.rb'
395
- mixin_patterns:
396
- - '../common/**/*.mixin.rb'
397
- - './mixins/**/*.mixin.rb'
398
- resource_paths:
399
- - '../common/resources'
400
- - './resources'
401
- }
402
-
403
-
404
- DEFAULT_ENV_CFG = %{cert: &cert ./resources/<root_cert>.cer
405
- http:
406
- <http_client_name>:
407
- base_url: http://localhost:5000/api/v1/
408
- # basic_auth:
409
- # username: <username>
410
- # password: <password>
411
- # keystone:
412
- # url: https://<keystone_url>/main/v3/
413
- # username: <username>
414
- # password: <password>
415
- # project: <project>
416
- # domain: <domain>
417
- # cert: *cert
418
- # ssh:
419
- # <ssh_client_name>:
420
- # host: <hostname>
421
- # username: <username>
422
- # password: <password>
423
- }
424
-
425
- DEFAULT_ENV_SECRET_CFG = %{http:
426
- <http_client_name>:
427
- # basic_auth:
428
- # username: <username>
429
- # password: <password>
430
- # keystone:
431
- # username: <username>
432
- # password: <password>
433
- # ssh:
434
- # <ssh_client_name>:
435
- # username: <username>
436
- # password: <password>
437
- }
438
-
439
- SAMPLE_SPEC = %[describe '<subject>' do
440
- it 'does some http requests', tags: [:sample] do
441
- log 'doing some http request'
442
-
443
- http '<http_client_name>' do
444
- auth 'basic'
445
- # auth 'keystone'
446
- method 'GET'
447
- path 'path/to/resource'
448
- param 'id', 4295118773
449
- param 'foo', 'bar'
450
- header 'X-Correlation-Id', '4c2367b1-bfee-4cc2-bdc5-ed17a6a9dd4b'
451
- header 'Range', 'bytes=500-999'
452
- json({
453
- "message": "Hello Spectre!"
454
- })
455
- end
456
-
457
- expect 'the response code to be 200' do
458
- response.code.should_be 200
459
- end
460
-
461
- expect 'a message to exist' do
462
- response.json.message.should_not_be nil
463
- end
464
- end
465
- end
466
- ]
467
-
468
- DEFAULT_GITIGNORE = %[*.code-workspace
469
- logs/
470
- reports/
471
- **/environments/*.env.secret.yml
472
- ]
473
-
474
- if action == 'init'
475
- DEFAULT_FILES = [
476
- ['./environments/default.env.yml', DEFAULT_ENV_CFG],
477
- ['./environments/default.env.secret.yml', DEFAULT_ENV_SECRET_CFG],
478
- ['./specs/sample.spec.rb', SAMPLE_SPEC],
479
- ['./spectre.yml', DEFAULT_SPECTRE_CFG],
480
- ['./.gitignore', DEFAULT_GITIGNORE],
481
- ]
482
-
483
- %w(environments logs specs).each do |dir_name|
484
- Dir.mkdir(dir_name) unless File.directory? dir_name
485
- end
486
-
487
- DEFAULT_FILES.each do |file, content|
488
- if not File.exists? file
489
- File.write(file, content)
490
- end
491
- end
492
-
493
- exit 0
494
- end
1
+ #! /usr/bin/ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'yaml'
5
+ require 'ostruct'
6
+ require 'optparse'
7
+ require 'fileutils'
8
+ require 'ectoplasm'
9
+
10
+ require_relative '../lib/spectre'
11
+
12
+
13
+ DEFAULT_CONFIG = {
14
+ 'config_file' => './spectre.yml',
15
+ 'environment' => 'default',
16
+ 'specs' => [],
17
+ 'tags' => [],
18
+ 'colored' => true,
19
+ 'verbose' => false,
20
+ 'reporters' => [
21
+ 'Spectre::Reporter::Console',
22
+ ],
23
+ 'loggers' => [
24
+ 'Spectre::Logger::Console',
25
+ 'Spectre::Logger::File',
26
+ ],
27
+ 'log_file' => './logs/spectre_<date>.log',
28
+ 'log_format' => {
29
+ 'console' => {
30
+ 'indent' => 2,
31
+ 'width' => 80,
32
+ 'end_context' => nil,
33
+ 'separator' => '<indent><desc>',
34
+ },
35
+ 'file' => {
36
+ 'separator' => '-- <desc>',
37
+ 'start_group' => "-- Start '<desc>'",
38
+ 'end_group' => "-- End '<desc>'",
39
+ },
40
+ },
41
+ 'debug' => false,
42
+ 'out_path' => './reports',
43
+ 'secure_keys' => ['password', 'secret', 'token', 'secure', 'authorization'],
44
+ 'spec_patterns' => ['./specs/**/*.spec.rb'],
45
+ 'mixin_patterns' => ['../common/mixins/**/*.mixin.rb', './mixins/**/*.mixin.rb'],
46
+ 'env_patterns' => ['./environments/**/*.env.yml'],
47
+ 'env_partial_patterns' => ['./environments/**/*.env.secret.yml'],
48
+ 'resource_paths' => ['../common/resources', './resources'],
49
+ 'modules' => [
50
+ 'spectre/helpers',
51
+ 'spectre/reporter/console',
52
+ 'spectre/reporter/junit',
53
+ 'spectre/logger/console',
54
+ 'spectre/logger/file',
55
+ 'spectre/assertion',
56
+ 'spectre/diagnostic',
57
+ 'spectre/environment',
58
+ 'spectre/mixin',
59
+ 'spectre/bag',
60
+ 'spectre/http',
61
+ 'spectre/http/basic_auth',
62
+ 'spectre/http/keystone',
63
+ 'spectre/resources',
64
+ ],
65
+ 'include' => [
66
+
67
+ ],
68
+ 'exclude' => [
69
+
70
+ ],
71
+ }
72
+
73
+
74
+ cmd_options = {}
75
+
76
+ opt_parser = OptionParser.new do |opts|
77
+ opts.banner = %{Spectre #{Spectre::VERSION}
78
+
79
+ Usage: spectre [command] [options]
80
+
81
+ Commands:
82
+ list List specs
83
+ run Run specs (default)
84
+ show Print current environment settings
85
+ dump Dumps the given environment in YAML format to console
86
+ init Initializes a new spectre project
87
+
88
+ Specific options:}
89
+
90
+ opts.on('-s SPEC,SPEC', '--specs SPEC,SPEC', Array, 'The specs to run') do |specs|
91
+ cmd_options['specs'] = specs
92
+ end
93
+
94
+ opts.on('-t TAG,TAG', '--tags TAG,TAG', Array, 'Run only specs with given tags') do |tags|
95
+ cmd_options['tags'] = tags
96
+ end
97
+
98
+ opts.on('-e NAME', '--env NAME', 'Name of the environment to load') do |env_name|
99
+ cmd_options['environment'] = env_name
100
+ end
101
+
102
+ opts.on('-c FILE', '--config FILE', 'Config file to load') do |file_path|
103
+ cmd_options['config_file'] = file_path
104
+ end
105
+
106
+ opts.on('--spec-pattern PATTERN', Array, 'File pattern for spec files') do |spec_pattern|
107
+ cmd_options['spec_patterns'] = spec_pattern
108
+ end
109
+
110
+ opts.on('--env-pattern PATTERN', Array, 'File pattern for environment files') do |env_patterns|
111
+ cmd_options['env_patterns'] = env_patterns
112
+ end
113
+
114
+ opts.on('--no-color', 'Disable colored output') do
115
+ cmd_options['colored'] = false
116
+ end
117
+
118
+ opts.on('--ignore-failure', 'Always exit with code 0') do
119
+ cmd_options['ignore_failure'] = true
120
+ end
121
+
122
+ opts.on('-o PATH', '--out PATH', 'Output directory path') do |path|
123
+ cmd_options['out_path'] = File.absolute_path(path)
124
+ end
125
+
126
+ opts.on('-r NAME', '--reporters NAME', Array, "A list of reporters to use") do |reporters|
127
+ cmd_options['reporters'] = reporters
128
+ end
129
+
130
+ opts.on('-d', '--debug', "Run in debug mode") do
131
+ cmd_options['debug'] = true
132
+ end
133
+
134
+ opts.on('-p KEY=VAL', '--property KEY=VAL', "Override config option. Use `spectre show` to get list of available options") do |option|
135
+ key, val = option.split '='
136
+ val = val.split ',' if DEFAULT_CONFIG[key].is_a? Array
137
+ val = ['true', '1'].include? val if [true, false].include? DEFAULT_CONFIG[key]
138
+ val = val.to_i if DEFAULT_CONFIG[key].is_a? Integer
139
+ cmd_options[key] = val
140
+
141
+ curr_opt = cmd_options
142
+ (key.split '.').each do |k|
143
+ curr_opt[k] = {} unless curr_opt.key? k
144
+ end
145
+ curr_opt = val
146
+ end
147
+
148
+ opts.separator "\nCommon options:"
149
+
150
+ opts.on_tail('--version', 'Print current installed version') do
151
+ puts Spectre::VERSION
152
+ exit
153
+ end
154
+
155
+ opts.on_tail('-h', '--help', 'Print this help') do
156
+ puts opts
157
+ exit
158
+ end
159
+ end.parse!
160
+
161
+
162
+ action = ARGV[0] || 'run'
163
+
164
+
165
+ ###########################################
166
+ # Load Config
167
+ ###########################################
168
+
169
+
170
+ cfg = {}
171
+ cfg.deep_merge! DEFAULT_CONFIG
172
+
173
+ global_config_file = File.join File.expand_path('~'), '.spectre'
174
+
175
+ if File.exists? global_config_file
176
+ global_options = YAML.load_file(global_config_file)
177
+ cfg.deep_merge! global_options if global_options
178
+ end
179
+
180
+ config_file = cmd_options['config_file'] || cfg['config_file']
181
+
182
+ if File.exists? config_file
183
+ file_options = YAML.load_file(config_file)
184
+ cfg.deep_merge! file_options
185
+ Dir.chdir File.dirname(config_file)
186
+ end
187
+
188
+ cfg.deep_merge! cmd_options
189
+
190
+
191
+ ###########################################
192
+ # Load Environment
193
+ ###########################################
194
+
195
+
196
+ envs = {}
197
+ read_env_files = {}
198
+ cfg['env_patterns'].each do |pattern|
199
+ Dir.glob(pattern).each do|f|
200
+ spec_env = YAML.load_file(f) || {}
201
+
202
+ name = spec_env['name'] || 'default'
203
+
204
+ if envs.key? name
205
+ existing_env_file = read_env_files[name]
206
+ puts "Duplicate environment definition detected with name #{name} in '#{f}'. Previously defined in '#{existing_env_file}'"
207
+ exit 1
208
+ end
209
+
210
+ read_env_files[name] = f
211
+ envs[name] = spec_env
212
+ end
213
+ end
214
+
215
+ # Merge partial environment configs with existing environments
216
+ cfg['env_partial_patterns'].each do |pattern|
217
+ Dir.glob(pattern).each do|f|
218
+ partial_env = YAML.load_file(f)
219
+ name = partial_env.delete('name') || 'default'
220
+ next unless envs.key? name
221
+
222
+ envs[name].deep_merge! partial_env
223
+ end
224
+ end
225
+
226
+ env = envs[cfg['environment']]
227
+ cfg.merge! env if env
228
+
229
+
230
+ String.colored! if cfg['colored']
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
+
236
+
237
+ ###########################################
238
+ # Load Specs
239
+ ###########################################
240
+
241
+
242
+ cfg['spec_patterns'].each do |pattern|
243
+ Dir.glob(pattern).each do|f|
244
+ require_relative File.join(Dir.pwd, f)
245
+ end
246
+ end
247
+
248
+
249
+ ###########################################
250
+ # List specs
251
+ ###########################################
252
+
253
+
254
+ if 'list' == action
255
+ colors = [:blue, :magenta, :yellow, :green]
256
+ specs = Spectre.specs(cfg['specs'], cfg['tags'])
257
+
258
+ exit 1 unless specs.any?
259
+
260
+ counter = 0
261
+
262
+ specs.group_by { |x| x.subject }.each do |subject, spec_group|
263
+ spec_group.each do |spec|
264
+ tags = spec.tags.map { |x| '#' + x.to_s }.join ' '
265
+ desc = subject.desc
266
+ desc += ' - ' + spec.context.__desc + ' -' if spec.context.__desc
267
+ desc += ' ' + spec.desc
268
+ puts "[#{spec.name}]".send(colors[counter % colors.length]) + " #{desc} #{tags.cyan}"
269
+ end
270
+
271
+ counter += 1
272
+ end
273
+
274
+ exit 0
275
+ end
276
+
277
+
278
+ ###########################################
279
+ # Run
280
+ ###########################################
281
+
282
+
283
+ if 'run' == action
284
+ # Initialize logger
285
+ now = Time.now
286
+
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
+ })
294
+
295
+ log_dir = File.dirname cfg['log_file']
296
+ FileUtils.makedirs log_dir unless Dir.exists? log_dir
297
+
298
+ # Load Modules
299
+
300
+ cfg['modules']
301
+ .concat(cfg['include'])
302
+ .select { |mod| !cfg['exclude'].include? mod }
303
+ .each do |mod|
304
+ begin
305
+ mod_file = mod + '.rb'
306
+ spectre_lib_mod = File.join(File.dirname(__dir__), 'lib', mod_file)
307
+
308
+ if File.exists? mod_file
309
+ require_relative mod_file
310
+
311
+ elsif File.exists? spectre_lib_mod
312
+ require_relative spectre_lib_mod
313
+
314
+ else
315
+ require mod
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
329
+ end
330
+
331
+ Spectre.configure(cfg)
332
+
333
+ Spectre::Logger.debug! if cfg['debug']
334
+
335
+ cfg['loggers'].each do |logger_name|
336
+ logger = Kernel.const_get(logger_name).new(cfg)
337
+ Spectre::Logger.add(logger)
338
+ end if cfg['loggers']
339
+
340
+ specs = Spectre.specs(cfg['specs'], cfg['tags'])
341
+
342
+ unless specs.any?
343
+ puts "No specs found in #{Dir.pwd}"
344
+ exit 1
345
+ end
346
+
347
+ run_infos = Spectre::Runner.new.run(specs)
348
+
349
+ cfg['reporters'].each do |reporter|
350
+ reporter = Kernel.const_get(reporter).new(cfg)
351
+ reporter.report(run_infos)
352
+ end
353
+
354
+ errors = run_infos.select { |x| nil != x.error or nil != x.failure }
355
+
356
+ exit 0 if cfg['ignore_failure'] or not errors.any?
357
+
358
+ exit 1
359
+ end
360
+
361
+
362
+ ###########################################
363
+ # Envs
364
+ ###########################################
365
+
366
+
367
+ if 'envs' == action
368
+ exit 1 unless envs.any?
369
+ puts envs.pretty
370
+ exit 0
371
+ end
372
+
373
+
374
+ ###########################################
375
+ # Show
376
+ ###########################################
377
+
378
+
379
+ if 'show' == action
380
+ puts cfg.pretty
381
+ exit 0
382
+ end
383
+
384
+
385
+ ###########################################
386
+ # Dump
387
+ ###########################################
388
+
389
+
390
+ if 'dump' == action
391
+ puts YAML.dump(cfg)
392
+ end
393
+
394
+
395
+ ###########################################
396
+ # Init
397
+ ###########################################
398
+
399
+ DEFAULT_SPECTRE_CFG = %{log_file: ./logs/spectre_<date>.log
400
+ env_patterns:
401
+ - './environments/**/*.env.yml'
402
+ env_partial_patterns:
403
+ - './environments/**/*.env.secret.yml'
404
+ spec_patterns:
405
+ - './specs/**/*.spec.rb'
406
+ mixin_patterns:
407
+ - '../common/**/*.mixin.rb'
408
+ - './mixins/**/*.mixin.rb'
409
+ resource_paths:
410
+ - '../common/resources'
411
+ - './resources'
412
+ }
413
+
414
+
415
+ DEFAULT_ENV_CFG = %{cert: &cert ./resources/<root_cert>.cer
416
+ http:
417
+ <http_client_name>:
418
+ base_url: http://localhost:5000/api/v1/
419
+ # basic_auth:
420
+ # username: <username>
421
+ # password: <password>
422
+ # keystone:
423
+ # url: https://<keystone_url>/main/v3/
424
+ # username: <username>
425
+ # password: <password>
426
+ # project: <project>
427
+ # domain: <domain>
428
+ # cert: *cert
429
+ # ssh:
430
+ # <ssh_client_name>:
431
+ # host: <hostname>
432
+ # username: <username>
433
+ # password: <password>
434
+ }
435
+
436
+ DEFAULT_ENV_SECRET_CFG = %{http:
437
+ <http_client_name>:
438
+ # basic_auth:
439
+ # username: <username>
440
+ # password: <password>
441
+ # keystone:
442
+ # username: <username>
443
+ # password: <password>
444
+ # ssh:
445
+ # <ssh_client_name>:
446
+ # username: <username>
447
+ # password: <password>
448
+ }
449
+
450
+ SAMPLE_SPEC = %[describe '<subject>' do
451
+ it 'does some http requests', tags: [:sample] do
452
+ log 'doing some http request'
453
+
454
+ http '<http_client_name>' do
455
+ auth 'basic'
456
+ # auth 'keystone'
457
+ method 'GET'
458
+ path 'path/to/resource'
459
+ param 'id', 4295118773
460
+ param 'foo', 'bar'
461
+ header 'X-Correlation-Id', '4c2367b1-bfee-4cc2-bdc5-ed17a6a9dd4b'
462
+ header 'Range', 'bytes=500-999'
463
+ json({
464
+ "message": "Hello Spectre!"
465
+ })
466
+ end
467
+
468
+ expect 'the response code to be 200' do
469
+ response.code.should_be 200
470
+ end
471
+
472
+ expect 'a message to exist' do
473
+ response.json.message.should_not_be nil
474
+ end
475
+ end
476
+ end
477
+ ]
478
+
479
+ DEFAULT_GITIGNORE = %[*.code-workspace
480
+ logs/
481
+ reports/
482
+ **/environments/*.env.secret.yml
483
+ ]
484
+
485
+ DEFAULT_GEMFILE = %[source 'https://rubygems.org'
486
+
487
+ gem 'spectre-core', '>= #{Spectre::VERSION}'
488
+ # gem 'spectre-mysql', '>= 1.0.0'
489
+ # gem 'spectre-ssh', '>= 1.0.0'
490
+ # gem 'spectre-ftp', '>= 1.0.0'
491
+ # gem 'spectre-curl', '>= 1.0.0'
492
+ # gem 'spectre-git', '>= 0.1.0'
493
+ ]
494
+
495
+ if 'init' == action
496
+ DEFAULT_FILES = [
497
+ ['./environments/default.env.yml', DEFAULT_ENV_CFG],
498
+ ['./environments/default.env.secret.yml', DEFAULT_ENV_SECRET_CFG],
499
+ ['./specs/sample.spec.rb', SAMPLE_SPEC],
500
+ ['./spectre.yml', DEFAULT_SPECTRE_CFG],
501
+ ['./.gitignore', DEFAULT_GITIGNORE],
502
+ ['./Gemfile', DEFAULT_GEMFILE],
503
+ ]
504
+
505
+ %w(environments logs specs).each do |dir_name|
506
+ Dir.mkdir(dir_name) unless File.directory? dir_name
507
+ end
508
+
509
+ DEFAULT_FILES.each do |file, content|
510
+ unless File.exists? file
511
+ File.write(file, content)
512
+ end
513
+ end
514
+
515
+ exit 0
516
+ end