webspicy 0.20.3 → 0.20.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 438c8ad5287da851bcbfe71f39fb3f53288949e16e4ba0e5c9fbdb12874c141c
4
- data.tar.gz: 1b575f4fa2d1b434885fe8a13f41c9975fb9e1d9528cc44cf0d08fa7b36e2306
3
+ metadata.gz: 9afe697a47ba4391d2e059f1bf3707c04f97f9d6fd50557104a59c6602dbd75c
4
+ data.tar.gz: 66ec4036f8e76dad7af0f8b0cf83ea139a67a7b1020aa0a304c26fdc9402d593
5
5
  SHA512:
6
- metadata.gz: 8d0d6d54fedfa5bb9ad1ba6aa1178b8e33db677ff1db5f3f56da73a6df75ee0523f08e6f04916669ce1fe13149c86ebdf826780e5520332c2d0211c95ee25f94
7
- data.tar.gz: d33ffb74de8d5d8e0f57af996b49aeb177beff8403f9ab5c22231cc77228112efa47c8373b1d55e957832f414c32b5cf42dbeca0ca58d27ffb037ecbf8c045d8
6
+ metadata.gz: 79feb96443a47523b38f16e4cf7e7edfcd675f5a71c6b33aa452ad452aeacd5e64de1ce1ffa9ff3f5bf9cf428d59dc183e8f1455e1ce26126f2eddf9a14795fb
7
+ data.tar.gz: 2761eb20d67f4c697dedf7c27496cfd36ceed4f988f1f54f17809358e570102f1e40c29c47e46f614671504dcf1c877ce2fe6ccb7a72b510994a9da95bb74de1
data/bin/webspicy CHANGED
@@ -55,5 +55,4 @@ if ARGV.size != 1
55
55
  end
56
56
 
57
57
  config = Webspicy::Configuration.dress(ARGV[0])
58
- res = Webspicy::Tester.new(config).call
59
- abort("#{res} errors occured") unless res == 0
58
+ Webspicy::Tester.new(config).call!
@@ -33,12 +33,15 @@ module Webspicy
33
33
  @service_filter = default_service_filter
34
34
  @test_case_filter = default_test_case_filter
35
35
  @colors = {
36
+ :section => :magenta,
36
37
  :highlight => :cyan,
37
38
  :error => :red,
38
39
  :success => :green
39
40
  }
41
+ @colorize = true
40
42
  @scope_factory = ->(config){ Scope.new(config) }
41
43
  @client = Web::HttpClient
44
+ @reporter = default_reporter
42
45
  Path.require_tree(@folder/'support') if (@folder/'support').exists?
43
46
  @world = Support::World.new(folder/'world', self)
44
47
  yield(self) if block_given?
@@ -47,6 +50,8 @@ module Webspicy
47
50
  protected :folder=
48
51
 
49
52
  attr_accessor :colors
53
+ attr_accessor :colorize
54
+
50
55
  attr_reader :world
51
56
 
52
57
  def self.dress(arg, &bl)
@@ -434,6 +439,16 @@ module Webspicy
434
439
  end
435
440
  private :default_rspec_options
436
441
 
442
+ # Returns the default reporter to use.
443
+ def default_reporter
444
+ @reporter = Tester::Reporter::Composite.new
445
+ @reporter << Tester::Reporter::Documentation.new
446
+ @reporter << Tester::Reporter::Exceptions.new
447
+ @reporter << Tester::Reporter::Summary.new
448
+ @reporter << Tester::Reporter::ErrorCount.new
449
+ end
450
+ attr_accessor :reporter
451
+
437
452
  # Returns the Data system to use for parsing schemas
438
453
  #
439
454
  # The data system associated with a configuration is build when the
@@ -23,6 +23,7 @@ module Webspicy
23
23
  folder = config.folder
24
24
  world = config.folder/"world"
25
25
  fs = folder.glob("**/*.yml").reject{|f| f.to_s.start_with?(world.to_s) }
26
+ fs = fs.sort
26
27
  fs = fs.select(&to_filter_proc(config.file_filter)) if apply_filter
27
28
  fs.each do |file|
28
29
  yield file, folder
@@ -4,9 +4,9 @@ module Webspicy
4
4
  class MissingConditionImpl
5
5
  include Post
6
6
 
7
- def check
7
+ def check!
8
8
  msg = matching_description.gsub(/\(x\)/, "<!>")
9
- raise "#{msg} (not instrumented)"
9
+ fail!("#{msg} (not instrumented)")
10
10
  end
11
11
 
12
12
  end # class MissingConditionImpl
@@ -4,9 +4,9 @@ module Webspicy
4
4
  class UnexpectedConditionImpl
5
5
  include Post
6
6
 
7
- def check
7
+ def check!
8
8
  msg = matching_description.gsub(/\( \)/, "<x>")
9
- raise "#{msg} (is instrumented)"
9
+ fail!("#{msg} (is instrumented)")
10
10
  end
11
11
 
12
12
  end # class UnexpectedConditionImpl
@@ -3,11 +3,17 @@ module Webspicy
3
3
  module Colorize
4
4
 
5
5
  def colorize(str, kind, config = nil)
6
+ return str if config && !config.colorize
6
7
  color = (config || self.config).colors[kind]
7
8
  ColorizedString[str].colorize(color)
8
9
  end
9
10
  module_function :colorize
10
11
 
12
+ def colorize_section(str, cfg = nil)
13
+ colorize(str, :section, cfg)
14
+ end
15
+ module_function :colorize_section
16
+
11
17
  def colorize_highlight(str, cfg = nil)
12
18
  colorize(str, :highlight, cfg)
13
19
  end
@@ -15,7 +15,7 @@ module Webspicy
15
15
  @test_case = nil
16
16
  @invocation = nil
17
17
  @invocation_error = nil
18
- @reporter = default_reporter
18
+ @reporter = @config.reporter
19
19
  end
20
20
  attr_reader :config, :scope, :hooks, :client
21
21
  attr_reader :specification, :spec_file
@@ -31,15 +31,6 @@ module Webspicy
31
31
  config.failfast
32
32
  end
33
33
 
34
- def default_reporter
35
- @reporter = Reporter::Composite.new
36
- #@reporter << Reporter::Progress.new
37
- @reporter << Reporter::Documentation.new
38
- @reporter << Reporter::Exceptions.new
39
- @reporter << Reporter::Summary.new
40
- @reporter << Reporter::ErrorCount.new
41
- end
42
-
43
34
  def call
44
35
  reporter.init(self)
45
36
  begin
@@ -50,6 +41,11 @@ module Webspicy
50
41
  reporter.find(Reporter::ErrorCount).report
51
42
  end
52
43
 
44
+ def call!
45
+ res = call
46
+ abort("KO") unless res == 0
47
+ end
48
+
53
49
  def find_and_call(method, url, mutation)
54
50
  unless tc = scope.find_test_case(method, url)
55
51
  raise Error, "No such service `#{method} #{url}`"
@@ -73,19 +69,15 @@ module Webspicy
73
69
  @scope = scope
74
70
  @hooks = Support::Hooks.for(scope.config)
75
71
  @client = scope.get_client
76
- reporter.before_all
77
- @hooks.fire_before_all(self)
78
- reporter.before_all_done
79
- reporter.before_scope
80
72
  run_scope
81
- reporter.scope_done
82
- reporter.after_all
83
- @hooks.fire_after_all(self)
84
- reporter.after_all_done
85
73
  end
86
74
  end
87
75
 
88
76
  def run_scope
77
+ reporter.before_all
78
+ hooks.fire_before_all(self)
79
+ reporter.before_all_done
80
+ reporter.before_scope
89
81
  scope.each_specification_file do |spec_file|
90
82
  @specification = load_specification(spec_file)
91
83
  if @specification
@@ -97,6 +89,10 @@ module Webspicy
97
89
  raise FailFast
98
90
  end
99
91
  end
92
+ reporter.scope_done
93
+ reporter.after_all
94
+ hooks.fire_after_all(self)
95
+ reporter.after_all_done
100
96
  end
101
97
 
102
98
  def load_specification(spec_file)
@@ -66,6 +66,11 @@ module Webspicy
66
66
  }
67
67
  end
68
68
 
69
+ def find(kind)
70
+ return self if self.is_a?(kind)
71
+ raise "Missing reporter #{kind}"
72
+ end
73
+
69
74
  protected
70
75
 
71
76
  def plural(word, count)
@@ -4,40 +4,56 @@ module Webspicy
4
4
  class Documentation < Reporter
5
5
 
6
6
  module Helpers
7
+ INDENT = " ".freeze
8
+
9
+ def spec_file_line(spec_file)
10
+ relative_path = Path(spec_file).relative_to(config.folder)
11
+ colorize_section(">> #{relative_path}", config)
12
+ end
13
+
7
14
  def spec_file_error_line(spec_file, ex)
8
- str = colorize_highlight(spec_file.to_s)
9
- str += "\n " + colorize_error("X #{ex.message}")
15
+ str = ""
16
+ str += colorize_error(INDENT + "X #{ex.message}", config)
10
17
  if ex.root_cause && ex.root_cause != ex
11
- str += "\n " + colorize_error("#{ex.root_cause.message}")
18
+ str += "\n"
19
+ str += INDENT + colorize_error("#{ex.root_cause.message}", config)
12
20
  end
13
21
  str
14
22
  end
15
23
 
16
24
  def service_line(service, test_case)
17
- str = service.to_s + ", " + test_case.to_s
18
- str = colorize_highlight(str)
25
+ str = "#{service}, #{test_case}"
26
+ str = colorize_highlight(str, config)
19
27
  end
20
28
 
21
29
  def check_success_line(check)
22
- " " + colorize_success("v") + " " + check.behavior
30
+ INDENT + colorize_success("v " + check.behavior, config)
23
31
  end
24
32
 
25
33
  def check_failure_line(check, ex)
26
- " " + colorize_error("F " + ex.message)
34
+ INDENT + colorize_error("F " + ex.message, config)
27
35
  end
28
36
 
29
37
  def check_error_line(check, ex)
30
- " " + colorize_error("E " + ex.message)
38
+ INDENT + colorize_error("E " + ex.message, config)
31
39
  end
32
40
  end
33
41
  include Helpers
34
42
 
35
43
  def spec_file_error(e)
44
+ io.puts spec_file_line(spec_file)
45
+ io.puts
36
46
  io.puts spec_file_error_line(spec_file, e)
37
47
  io.puts
38
48
  io.flush
39
49
  end
40
50
 
51
+ def before_service
52
+ io.puts spec_file_line(spec_file)
53
+ io.puts
54
+ io.flush
55
+ end
56
+
41
57
  def before_test_case
42
58
  io.puts service_line(service, test_case)
43
59
  io.flush
@@ -5,18 +5,22 @@ module Webspicy
5
5
 
6
6
  def initialize(*args, &bl)
7
7
  super
8
- @error_count = 0
8
+ @errors = Hash.new{|h,k| 0 }
9
9
  end
10
+ attr_reader :errors
10
11
 
11
- def on_error(*args, &bl)
12
- @error_count += 1
12
+ [
13
+ :spec_file_error,
14
+ :check_error,
15
+ :check_failure
16
+ ].each do |meth|
17
+ define_method(meth) do |*args, &bl|
18
+ @errors[meth] += 1
19
+ end
13
20
  end
14
- alias :spec_file_error :on_error
15
- alias :check_failure :on_error
16
- alias :check_error :on_error
17
21
 
18
22
  def report
19
- @error_count
23
+ @errors.values.inject(0){|memo,x| memo+x }
20
24
  end
21
25
 
22
26
  end # class ErrorCount
@@ -4,12 +4,12 @@ module Webspicy
4
4
  class FileProgress < Reporter
5
5
 
6
6
  def spec_file_error(e)
7
- io.print colorize_error("X")
7
+ io.print colorize_error("X", config)
8
8
  io.flush
9
9
  end
10
10
 
11
11
  def spec_file_done
12
- io.print colorize_success(".")
12
+ io.print colorize_success(".", config)
13
13
  io.flush
14
14
  end
15
15
 
@@ -22,9 +22,9 @@ module Webspicy
22
22
  msg = "#{plural('spec file', spec_files_count)}, "\
23
23
  "#{plural('error', errors_count)}"
24
24
  if success?
25
- msg = colorize_success(msg)
25
+ msg = colorize_success(msg, config)
26
26
  else
27
- msg = colorize_error(msg)
27
+ msg = colorize_error(msg, config)
28
28
  end
29
29
  io.puts(msg)
30
30
  io.puts
@@ -4,16 +4,16 @@ module Webspicy
4
4
  class Progress < Reporter
5
5
 
6
6
  def spec_file_error(e)
7
- io.print colorize_error("X")
7
+ io.print colorize_error("X", config)
8
8
  end
9
9
 
10
10
  def after_each_done
11
11
  if result.success?
12
- io.print colorize_success(".")
12
+ io.print colorize_success(".", config)
13
13
  elsif result.failure?
14
- io.print colorize_error("F")
14
+ io.print colorize_error("F", config)
15
15
  elsif result.error?
16
- io.print colorize_error("E")
16
+ io.print colorize_error("E", config)
17
17
  end
18
18
  io.flush
19
19
  end
@@ -9,18 +9,21 @@ module Webspicy
9
9
  @examples_count = 0
10
10
  @counterexamples_count = 0
11
11
  @assertions_count = 0
12
+ #
13
+ @spec_file_errors_count = 0
12
14
  @errors_count = 0
13
15
  @failures_count = 0
14
16
  end
15
17
  attr_reader :spec_files_count, :examples_count, :counterexamples_count
16
- attr_reader :assertions_count, :errors_count, :failures_count
18
+ attr_reader :assertions_count
19
+ attr_reader :spec_file_errors_count, :errors_count, :failures_count
17
20
 
18
21
  def before_spec_file
19
22
  @spec_files_count += 1
20
23
  end
21
24
 
22
25
  def spec_file_error(e)
23
- @errors_count += 1
26
+ @spec_file_errors_count += 1
24
27
  end
25
28
 
26
29
  def after_each_done
@@ -42,19 +45,17 @@ module Webspicy
42
45
  "#{plural('error', errors_count)}, "\
43
46
  "#{plural('failure', failures_count)}"
44
47
  if success?
45
- msg = colorize_success(msg)
48
+ msg = colorize_success(msg, config)
46
49
  else
47
- msg = colorize_error(msg)
50
+ msg = colorize_error(msg, config)
48
51
  end
49
52
  io.puts(msg)
50
53
  io.puts
51
54
  io.flush
52
55
  end
53
56
 
54
- private
55
-
56
57
  def success?
57
- @errors_count == 0 && @failures_count == 0
58
+ @spec_file_errors_count == 0 && @errors_count == 0 && @failures_count == 0
58
59
  end
59
60
 
60
61
  end # class Summary
@@ -18,9 +18,7 @@ module Webspicy
18
18
  end
19
19
 
20
20
  def call
21
- if err = post.check!
22
- _! err
23
- end
21
+ post.check!
24
22
  end
25
23
 
26
24
  end # class ErrconditionMet
@@ -18,9 +18,7 @@ module Webspicy
18
18
  end
19
19
 
20
20
  def call
21
- if err = post.check!
22
- _! err
23
- end
21
+ post.check!
24
22
  end
25
23
 
26
24
  end # class PostconditionMet
@@ -2,7 +2,7 @@ module Webspicy
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 20
5
- TINY = 3
5
+ TINY = 4
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
@@ -0,0 +1,24 @@
1
+ ---
2
+ command:
3
+ webspicy {options} {args}
4
+
5
+ examples:
6
+
7
+ - description: |-
8
+ when called on a passing path
9
+ args:
10
+ - ./fixtures/passing/config.rb
11
+ assert:
12
+ exit_code:
13
+ 0
14
+ stdout: |-
15
+ GET /, when requested
16
+ v It has a 200 response status
17
+ v It has a `Content-Type: application/json` response header
18
+ v Its output meets the expected data schema
19
+ v Assert notEmpty
20
+ v Assert pathFD('', :hello => "World" )
21
+
22
+
23
+ 1 spec file, 1 example, 0 counterexample
24
+ 5 assertions, 0 error, 0 failure
@@ -0,0 +1,9 @@
1
+ Webspicy::Configuration.new(Path.dir) do |c|
2
+ app = ->(env){
3
+ [ 200,
4
+ {"Content-Type" => "application/json"},
5
+ [ {hello: "World"}.to_json ]
6
+ ]
7
+ }
8
+ c.client = Webspicy::Tester::RackTestClient.for(app)
9
+ end
@@ -0,0 +1,30 @@
1
+ ---
2
+ url: |-
3
+ /
4
+
5
+ method: |-
6
+ GET
7
+
8
+ description: |-
9
+ Returns hello world
10
+
11
+ input_schema: |-
12
+ { }
13
+
14
+ output_schema: |-
15
+ { hello: String }
16
+
17
+ error_schema: |-
18
+ .
19
+
20
+ examples:
21
+
22
+ - description: |-
23
+ when requested
24
+ params: {}
25
+ expected:
26
+ content_type: application/json
27
+ status: 200
28
+ assert:
29
+ - notEmpty
30
+ - pathFD('', :hello => "World" )
data/tasks/test.rake CHANGED
@@ -18,7 +18,8 @@ namespace :test do
18
18
  desc "Runs the integration tests on the #{file.basename} example"
19
19
  task(test_name) do
20
20
  Bundler.with_original_env do
21
- system("cd #{file} && bundle exec rake")
21
+ x = system("cd #{file} && bundle exec rake")
22
+ abort("Example test suite failed: #{file}") unless x
22
23
  end
23
24
  end
24
25
  tests << test_name
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webspicy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.3
4
+ version: 0.20.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-12 00:00:00.000000000 Z
11
+ date: 2021-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -126,22 +126,22 @@ dependencies:
126
126
  name: rack-robustness
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: 1.1.0
132
129
  - - "~>"
133
130
  - !ruby/object:Gem::Version
134
131
  version: '1.1'
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: 1.1.0
135
135
  type: :runtime
136
136
  prerelease: false
137
137
  version_requirements: !ruby/object:Gem::Requirement
138
138
  requirements:
139
- - - ">="
140
- - !ruby/object:Gem::Version
141
- version: 1.1.0
142
139
  - - "~>"
143
140
  - !ruby/object:Gem::Version
144
141
  version: '1.1'
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: 1.1.0
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: mustermann
147
147
  requirement: !ruby/object:Gem::Requirement
@@ -284,6 +284,9 @@ files:
284
284
  - lib/webspicy/web/mocker/config.ru
285
285
  - lib/webspicy/web/openapi.rb
286
286
  - lib/webspicy/web/openapi/generator.rb
287
+ - spec/blackbox/commandline.yml
288
+ - spec/blackbox/fixtures/passing/config.rb
289
+ - spec/blackbox/fixtures/passing/formaldef/get.yml
287
290
  - spec/spec_helper.rb
288
291
  - spec/unit/configuration/config.rb
289
292
  - spec/unit/configuration/scope/test_each_service.rb
@@ -317,7 +320,7 @@ homepage: http://github.com/enspirit/webspicy
317
320
  licenses:
318
321
  - MIT
319
322
  metadata: {}
320
- post_install_message:
323
+ post_install_message:
321
324
  rdoc_options: []
322
325
  require_paths:
323
326
  - lib
@@ -332,8 +335,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
332
335
  - !ruby/object:Gem::Version
333
336
  version: '0'
334
337
  requirements: []
335
- rubygems_version: 3.0.8
336
- signing_key:
338
+ rubygems_version: 3.1.4
339
+ signing_key:
337
340
  specification_version: 4
338
341
  summary: Webspicy helps testing web services as software operation black boxes!
339
342
  test_files: []