spectre-core 1.10.0 → 1.12.2
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 +39 -20
- 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 +68 -27
- data/lib/spectre/http/basic_auth.rb +5 -2
- data/lib/spectre/http/keystone.rb +76 -73
- data/lib/spectre/http.rb +379 -358
- 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 +2 -5
- data/lib/spectre/reporter/junit.rb +5 -3
- data/lib/spectre/resources.rb +7 -4
- data/lib/spectre.rb +58 -45
- metadata +12 -12
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: b85338c15a8c29d520ed02d2e6816a64c579b6edd654f3d047fbeddb4a5c0ea3
         | 
| 4 | 
            +
              data.tar.gz: 7be4646412f7dd3a971b21269215cddff5398cc12a50cd42dcd78a6bb70bf012
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 043d7b2bda42acf5687f09ce9468c8b3ce01566c5a61d3d1c753b9d61a126898b883f00b67be67d6d61600a85143475e8b041b31fdf42f02dee5aca48260037c
         | 
| 7 | 
            +
              data.tar.gz: 890154e9fabf2664d50289f5eeb212cd9ea508a967341d9b27a2ad5dd329600542a168352274d4a0ca09dbe9aa91f3bc22e6c855d36a80e1219ccac9132dd047
         | 
    
        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 |  | 
| @@ -10,7 +12,7 @@ module Spectre | |
| 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)
         | 
| @@ -22,7 +24,7 @@ module Spectre | |
| 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)
         | 
| @@ -91,15 +108,14 @@ module Spectre | |
| 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
         | 
| @@ -118,7 +134,7 @@ module Spectre | |
| 118 134 | 
             
                  end
         | 
| 119 135 |  | 
| 120 136 | 
             
                  def should_contain(value)
         | 
| 121 | 
            -
                    raise AssertionFailure.new(" | 
| 137 | 
            +
                    raise AssertionFailure.new("The value is nil") if value.nil?
         | 
| 122 138 |  | 
| 123 139 | 
             
                    predicate = proc { |x| self.include? x.to_s }
         | 
| 124 140 | 
             
                    evaluation = SingleEvaluation.new(value)
         | 
| @@ -145,7 +161,6 @@ module Spectre | |
| 145 161 | 
             
                  alias :& :and
         | 
| 146 162 | 
             
                end
         | 
| 147 163 |  | 
| 148 | 
            -
             | 
| 149 164 | 
             
                class Evaluation
         | 
| 150 165 | 
             
                  def initialize value, other
         | 
| 151 166 | 
             
                    @value = value
         | 
| @@ -164,7 +179,6 @@ module Spectre | |
| 164 179 | 
             
                  alias :& :and
         | 
| 165 180 | 
             
                end
         | 
| 166 181 |  | 
| 167 | 
            -
             | 
| 168 182 | 
             
                class SingleEvaluation < Evaluation
         | 
| 169 183 | 
             
                  def initialize value
         | 
| 170 184 | 
             
                    super(value, nil)
         | 
| @@ -179,7 +193,6 @@ module Spectre | |
| 179 193 | 
             
                  end
         | 
| 180 194 | 
             
                end
         | 
| 181 195 |  | 
| 182 | 
            -
             | 
| 183 196 | 
             
                class OrEvaluation < Evaluation
         | 
| 184 197 | 
             
                  def initialize value, other
         | 
| 185 198 | 
             
                    super(value, other)
         | 
| @@ -194,7 +207,6 @@ module Spectre | |
| 194 207 | 
             
                  end
         | 
| 195 208 | 
             
                end
         | 
| 196 209 |  | 
| 197 | 
            -
             | 
| 198 210 | 
             
                class AndEvaluation < Evaluation
         | 
| 199 211 | 
             
                  def initialize value, other
         | 
| 200 212 | 
             
                    super(value, other)
         | 
| @@ -209,7 +221,6 @@ module Spectre | |
| 209 221 | 
             
                  end
         | 
| 210 222 | 
             
                end
         | 
| 211 223 |  | 
| 212 | 
            -
             | 
| 213 224 | 
             
                class AssertionFailure < ExpectationFailure
         | 
| 214 225 | 
             
                  attr_reader :expected, :actual
         | 
| 215 226 |  | 
| @@ -229,14 +240,11 @@ module Spectre | |
| 229 240 | 
             
                      Logger.log_process("expect #{desc}")
         | 
| 230 241 | 
             
                      yield
         | 
| 231 242 | 
             
                      Logger.log_status(desc, Logger::Status::OK)
         | 
| 232 | 
            -
             | 
| 233 243 | 
             
                    rescue Interrupt => e
         | 
| 234 244 | 
             
                      raise e
         | 
| 235 | 
            -
             | 
| 236 245 | 
             
                    rescue AssertionFailure => e
         | 
| 237 246 | 
             
                      Logger.log_status(desc, Logger::Status::FAILED)
         | 
| 238 247 | 
             
                      raise AssertionFailure.new(e.message, e.expected, e.actual, desc), cause: nil
         | 
| 239 | 
            -
             | 
| 240 248 | 
             
                    rescue Exception => e
         | 
| 241 249 | 
             
                      Logger.log_status(desc, Logger::Status::ERROR)
         | 
| 242 250 | 
             
                      raise AssertionFailure.new("An unexpected error occured during expectation: #{e.message}", nil, nil, desc), cause: e
         | 
| @@ -244,15 +252,21 @@ module Spectre | |
| 244 252 | 
             
                  end
         | 
| 245 253 |  | 
| 246 254 | 
             
                  def observe desc = nil
         | 
| 255 | 
            +
                    prefix = 'observing'
         | 
| 256 | 
            +
                    prefix += " '#{desc}'" if desc
         | 
| 257 | 
            +
             | 
| 247 258 | 
             
                    begin
         | 
| 248 | 
            -
                      Logger.log_info( | 
| 259 | 
            +
                      Logger.log_info(prefix) if desc
         | 
| 249 260 | 
             
                      yield
         | 
| 250 261 | 
             
                      @@success = true
         | 
| 251 | 
            -
             | 
| 262 | 
            +
                      @@logger.info("#{prefix} finished with success")
         | 
| 252 263 | 
             
                    rescue Interrupt => e
         | 
| 253 264 | 
             
                      raise e
         | 
| 254 | 
            -
             | 
| 255 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)
         | 
| 256 270 | 
             
                      @@success = false
         | 
| 257 271 | 
             
                    end
         | 
| 258 272 | 
             
                  end
         | 
| @@ -266,6 +280,11 @@ module Spectre | |
| 266 280 | 
             
                  end
         | 
| 267 281 | 
             
                end
         | 
| 268 282 |  | 
| 283 | 
            +
                Spectre.register do |config|
         | 
| 284 | 
            +
                  @@logger = ::Logger.new(config['log_file'], progname: 'spectre/assertion')
         | 
| 285 | 
            +
                  @@debug = config['debug']
         | 
| 286 | 
            +
                end
         | 
| 287 | 
            +
             | 
| 269 288 | 
             
                Spectre.delegate :expect, :observe, :success?, :fail_with, to: self
         | 
| 270 289 | 
             
              end
         | 
| 271 290 | 
             
            end
         | 
    
        data/lib/spectre/bag.rb
    CHANGED
    
    
    
        data/lib/spectre/curl.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            require_relative '../spectre'
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require 'open3'
         | 
| 2 4 | 
             
            require 'ostruct'
         | 
| 3 5 |  | 
| @@ -21,17 +23,17 @@ module Spectre::Curl | |
| 21 23 | 
             
                end
         | 
| 22 24 |  | 
| 23 25 | 
             
                def header name, value
         | 
| 24 | 
            -
                  @__req['headers'] = []  | 
| 26 | 
            +
                  @__req['headers'] = [] unless @__req['headers']
         | 
| 25 27 | 
             
                  @__req['headers'].append [name, value.to_s.strip]
         | 
| 26 28 | 
             
                end
         | 
| 27 29 |  | 
| 28 30 | 
             
                def param name, value
         | 
| 29 | 
            -
                  @__req['query'] = []  | 
| 31 | 
            +
                  @__req['query'] = [] unless @__req['query']
         | 
| 30 32 | 
             
                  @__req['query'].append [name, value.to_s.strip]
         | 
| 31 33 | 
             
                end
         | 
| 32 34 |  | 
| 33 35 | 
             
                def content_type media_type
         | 
| 34 | 
            -
                  @__req['headers'] = []  | 
| 36 | 
            +
                  @__req['headers'] = [] unless @__req['headers']
         | 
| 35 37 | 
             
                  @__req['headers'].append ['Content-Type', media_type]
         | 
| 36 38 | 
             
                end
         | 
| 37 39 |  | 
| @@ -111,7 +113,7 @@ module Spectre::Curl | |
| 111 113 | 
             
                end
         | 
| 112 114 |  | 
| 113 115 | 
             
                def json
         | 
| 114 | 
            -
                  return nil  | 
| 116 | 
            +
                  return nil unless @res[:body]
         | 
| 115 117 |  | 
| 116 118 | 
             
                  if @data == nil
         | 
| 117 119 | 
             
                    begin
         | 
| @@ -161,28 +163,31 @@ module Spectre::Curl | |
| 161 163 |  | 
| 162 164 | 
             
                  if @@http_cfg.key? name
         | 
| 163 165 | 
             
                    req.merge! @@http_cfg[name]
         | 
| 164 | 
            -
                    raise "No `base_url' set for HTTP client '#{name}'. Check your HTTP config in your environment."  | 
| 166 | 
            +
                    raise "No `base_url' set for HTTP client '#{name}'. Check your HTTP config in your environment." unless req['base_url']
         | 
| 165 167 | 
             
                  else
         | 
| 166 168 | 
             
                    req['base_url'] = name
         | 
| 167 169 | 
             
                  end
         | 
| 168 170 |  | 
| 169 | 
            -
                  SpectreHttpRequest.new(req). | 
| 171 | 
            +
                  SpectreHttpRequest.new(req)._evaluate(&block) if block_given?
         | 
| 170 172 |  | 
| 171 173 | 
             
                  invoke(req)
         | 
| 172 174 | 
             
                end
         | 
| 173 175 |  | 
| 174 176 | 
             
                def curl_request
         | 
| 175 177 | 
             
                  raise 'No request has been invoked yet' unless @@request
         | 
| 178 | 
            +
             | 
| 176 179 | 
             
                  @@request
         | 
| 177 180 | 
             
                end
         | 
| 178 181 |  | 
| 179 182 | 
             
                def curl_response
         | 
| 180 183 | 
             
                  raise 'There is no response. No request has been invoked yet.' unless @@response
         | 
| 184 | 
            +
             | 
| 181 185 | 
             
                  @@response
         | 
| 182 186 | 
             
                end
         | 
| 183 187 |  | 
| 184 188 | 
             
                def register mod
         | 
| 185 189 | 
             
                  raise 'Module must not be nil' unless mod
         | 
| 190 | 
            +
             | 
| 186 191 | 
             
                  @@modules << mod
         | 
| 187 192 | 
             
                end
         | 
| 188 193 |  | 
| @@ -192,7 +197,8 @@ module Spectre::Curl | |
| 192 197 | 
             
                  return str unless str or str.empty?
         | 
| 193 198 |  | 
| 194 199 | 
             
                  begin
         | 
| 195 | 
            -
                    json = JSON.parse | 
| 200 | 
            +
                    json = JSON.parse(str)
         | 
| 201 | 
            +
                    json.obfuscate!(@@secure_keys) unless @@debug
         | 
| 196 202 |  | 
| 197 203 | 
             
                    if pretty
         | 
| 198 204 | 
             
                      str = JSON.pretty_generate(json)
         | 
| @@ -206,6 +212,25 @@ module Spectre::Curl | |
| 206 212 | 
             
                  str
         | 
| 207 213 | 
             
                end
         | 
| 208 214 |  | 
| 215 | 
            +
                def secure? key
         | 
| 216 | 
            +
                  @@secure_keys.any? { |x| key.to_s.downcase.include? x.downcase }
         | 
| 217 | 
            +
                end
         | 
| 218 | 
            +
             | 
| 219 | 
            +
                def header_to_s headers
         | 
| 220 | 
            +
                  s = ''
         | 
| 221 | 
            +
             | 
| 222 | 
            +
                  return s unless headers
         | 
| 223 | 
            +
             | 
| 224 | 
            +
                  headers.each do |header|
         | 
| 225 | 
            +
                    key = header[0].to_s
         | 
| 226 | 
            +
                    value = header[1].to_s
         | 
| 227 | 
            +
                    value = '*****' if secure?(key) and not @@debug
         | 
| 228 | 
            +
                    s += "#{key.ljust(30, '.')}: #{value}\n"
         | 
| 229 | 
            +
                  end
         | 
| 230 | 
            +
             | 
| 231 | 
            +
                  s
         | 
| 232 | 
            +
                end
         | 
| 233 | 
            +
             | 
| 209 234 | 
             
                def invoke req
         | 
| 210 235 | 
             
                  cmd = [@@curl_path]
         | 
| 211 236 |  | 
| @@ -217,12 +242,12 @@ module Spectre::Curl | |
| 217 242 |  | 
| 218 243 | 
             
                  uri = req['base_url']
         | 
| 219 244 |  | 
| 220 | 
            -
                   | 
| 245 | 
            +
                  unless uri.match /http(?:s)?:\/\//
         | 
| 221 246 | 
             
                    uri = scheme + '://' + uri
         | 
| 222 247 | 
             
                  end
         | 
| 223 248 |  | 
| 224 249 | 
             
                  if req['path']
         | 
| 225 | 
            -
                    uri += '/'  | 
| 250 | 
            +
                    uri += '/' unless uri.end_with? '/'
         | 
| 226 251 | 
             
                    uri += req['path']
         | 
| 227 252 | 
             
                  end
         | 
| 228 253 |  | 
| @@ -230,11 +255,11 @@ module Spectre::Curl | |
| 230 255 | 
             
                    uri += '?'
         | 
| 231 256 | 
             
                    uri += req['query']
         | 
| 232 257 | 
             
                      .map { |x| x.join '='}
         | 
| 233 | 
            -
                      .join | 
| 258 | 
            +
                      .join('&')
         | 
| 234 259 | 
             
                  end
         | 
| 235 260 |  | 
| 236 | 
            -
                  cmd.append | 
| 237 | 
            -
                  cmd.append | 
| 261 | 
            +
                  cmd.append('"' + uri + '"')
         | 
| 262 | 
            +
                  cmd.append('-X', req['method']) unless req['method'] == 'GET' or (req['body'] and req['method'] == 'POST')
         | 
| 238 263 |  | 
| 239 264 | 
             
                  # Call all registered modules
         | 
| 240 265 | 
             
                  @@modules.each do |mod|
         | 
| @@ -243,43 +268,42 @@ module Spectre::Curl | |
| 243 268 |  | 
| 244 269 | 
             
                  # Add headers to curl command
         | 
| 245 270 | 
             
                  req['headers'].each do |header|
         | 
| 246 | 
            -
                    cmd.append | 
| 271 | 
            +
                    cmd.append('-H', '"' + header.join(':') + '"')
         | 
| 247 272 | 
             
                  end if req['headers']
         | 
| 248 273 |  | 
| 249 274 | 
             
                  # Add request body
         | 
| 250 275 | 
             
                  if req['body'] != nil and not req['body'].empty?
         | 
| 251 276 | 
             
                    req_body = try_format_json(req['body']).gsub(/"/, '\\"')
         | 
| 252 | 
            -
                    cmd.append | 
| 277 | 
            +
                    cmd.append('-d', '"' + req_body + '"')
         | 
| 253 278 | 
             
                  elsif ['POST', 'PUT', 'PATCH'].include? req['method'].upcase
         | 
| 254 | 
            -
                    cmd.append | 
| 279 | 
            +
                    cmd.append('-d', '"\n"')
         | 
| 255 280 | 
             
                  end
         | 
| 256 281 |  | 
| 257 282 | 
             
                  # Add certificate path if one if given
         | 
| 258 283 | 
             
                  if req['cert']
         | 
| 259 284 | 
             
                    raise "Certificate '#{req['cert']}' does not exist" unless File.exists? req['cert']
         | 
| 260 | 
            -
             | 
| 285 | 
            +
             | 
| 286 | 
            +
                    cmd.append('--cacert', req['cert'])
         | 
| 261 287 | 
             
                  elsif req['use_ssl'] or uri.start_with? 'https'
         | 
| 262 | 
            -
                    cmd.append | 
| 288 | 
            +
                    cmd.append('-k')
         | 
| 263 289 | 
             
                  end
         | 
| 264 290 |  | 
| 265 | 
            -
                  cmd.append | 
| 266 | 
            -
                  cmd.append | 
| 291 | 
            +
                  cmd.append('-i')
         | 
| 292 | 
            +
                  cmd.append('-v')
         | 
| 267 293 |  | 
| 268 | 
            -
                  @@request = OpenStruct.new | 
| 294 | 
            +
                  @@request = OpenStruct.new(req)
         | 
| 269 295 |  | 
| 270 | 
            -
                  sys_cmd = cmd.join | 
| 296 | 
            +
                  sys_cmd = cmd.join(' ')
         | 
| 271 297 |  | 
| 272 | 
            -
                  @@logger.debug | 
| 298 | 
            +
                  @@logger.debug(sys_cmd)
         | 
| 273 299 |  | 
| 274 300 | 
             
                  req_id = SecureRandom.uuid()[0..5]
         | 
| 275 301 |  | 
| 276 302 | 
             
                  req_log = "[>] #{req_id} #{req['method']} #{uri}\n"
         | 
| 277 | 
            -
                  req['headers'] | 
| 278 | 
            -
             | 
| 279 | 
            -
                  end if req['headers']
         | 
| 280 | 
            -
                  req_log += req['body'] if req['body'] != nil and not req['body'].empty?
         | 
| 303 | 
            +
                  req_log += header_to_s(req['headers'])
         | 
| 304 | 
            +
                  req_log += try_format_json(req['body'], pretty: true)
         | 
| 281 305 |  | 
| 282 | 
            -
                  @@logger.info | 
| 306 | 
            +
                  @@logger.info(req_log)
         | 
| 283 307 |  | 
| 284 308 | 
             
                  start_time = Time.now
         | 
| 285 309 |  | 
| @@ -295,9 +319,9 @@ module Spectre::Curl | |
| 295 319 |  | 
| 296 320 | 
             
                  # debug_log.lines.each { |x| @@logger.debug x unless x.empty? }
         | 
| 297 321 |  | 
| 298 | 
            -
                  raise "Unable to request #{uri}. Please check if this  | 
| 322 | 
            +
                  raise "Unable to request #{uri}. Please check if this URL is correctly configured and reachable." unless output
         | 
| 299 323 |  | 
| 300 | 
            -
                  @@logger.debug | 
| 324 | 
            +
                  @@logger.debug("[<] #{req_id} stdout:\n#{output}")
         | 
| 301 325 |  | 
| 302 326 | 
             
                  header, body = output.split /\r?\n\r?\n/
         | 
| 303 327 |  | 
| @@ -323,7 +347,7 @@ module Spectre::Curl | |
| 323 347 | 
             
                    code: match[:code].to_i,
         | 
| 324 348 | 
             
                    message: match[:message],
         | 
| 325 349 | 
             
                    headers: Hash[res_headers],
         | 
| 326 | 
            -
                    body: body
         | 
| 350 | 
            +
                    body: body,
         | 
| 327 351 | 
             
                  }
         | 
| 328 352 |  | 
| 329 353 | 
             
                  # Call all registered modules
         | 
| @@ -342,7 +366,7 @@ module Spectre::Curl | |
| 342 366 |  | 
| 343 367 | 
             
                  @@logger.info res_log
         | 
| 344 368 |  | 
| 345 | 
            -
                  @@response = SpectreHttpResponse.new | 
| 369 | 
            +
                  @@response = SpectreHttpResponse.new(res)
         | 
| 346 370 |  | 
| 347 371 | 
             
                  raise "Response did not indicate success: #{@@response.code} #{@@response.message}" if req['ensure_success'] and not @@response.success?
         | 
| 348 372 |  | 
| @@ -351,7 +375,12 @@ module Spectre::Curl | |
| 351 375 | 
             
              end
         | 
| 352 376 |  | 
| 353 377 | 
             
              Spectre.register do |config|
         | 
| 354 | 
            -
                @@ | 
| 378 | 
            +
                @@debug = config['debug']
         | 
| 379 | 
            +
             | 
| 380 | 
            +
                @@logger = ::Logger.new(config['log_file'], progname: 'spectre/curl')
         | 
| 381 | 
            +
                @@logger.level = @@debug ? Logger::DEBUG : Logger::INFO
         | 
| 382 | 
            +
             | 
| 383 | 
            +
                @@secure_keys = config['secure_keys'] || []
         | 
| 355 384 |  | 
| 356 385 | 
             
                @@curl_path = config['curl_path'] || 'curl'
         | 
| 357 386 |  | 
| @@ -365,4 +394,4 @@ module Spectre::Curl | |
| 365 394 | 
             
              end
         | 
| 366 395 |  | 
| 367 396 | 
             
              Spectre.delegate :curl, :curl_response, :curl_request, to: self
         | 
| 368 | 
            -
            end
         | 
| 397 | 
            +
            end
         | 
    
        data/lib/spectre/diagnostic.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            require_relative '../spectre'
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module Spectre
         | 
| 2 4 | 
             
              module Diagnostic
         | 
| 3 5 | 
             
                module Stopwatch
         | 
| @@ -21,9 +23,17 @@ module Spectre | |
| 21 23 | 
             
                    def duration
         | 
| 22 24 | 
             
                      @@end_time - @@start_time
         | 
| 23 25 | 
             
                    end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    def started_at
         | 
| 28 | 
            +
                      @@start_time
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    def finished_at
         | 
| 32 | 
            +
                      @@end_time
         | 
| 33 | 
            +
                    end
         | 
| 24 34 | 
             
                  end
         | 
| 25 35 |  | 
| 26 | 
            -
                  Spectre.delegate :start_watch, :stop_watch, :duration, :measure, to:  | 
| 36 | 
            +
                  Spectre.delegate :start_watch, :stop_watch, :duration, :measure, to: self
         | 
| 27 37 | 
             
                end
         | 
| 28 38 | 
             
              end
         | 
| 29 | 
            -
            end
         | 
| 39 | 
            +
            end
         |