webspicy 0.25.0 → 0.27.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b98da2f8756ded7b4d4a71d2eb227e2adfe25b4fd2922980e9de05a8ecd9ad65
4
- data.tar.gz: 4a3c22b30c47e27fe8bc61ad804e5eac6cff87435741f91bd533a59aba7a69ba
3
+ metadata.gz: 380f6a89f3f35f4a553b2b8892a16600aa203cf478ce1029cb93be2348fff658
4
+ data.tar.gz: 1b36d9aaefdd4aa437bc1a50eac2ddfff9c36230c4ff848328681c1eed1c6a83
5
5
  SHA512:
6
- metadata.gz: 557e4a8249210b4c64f84c6d9b41f56487d3e4a6ef2ec62a7e80783432de06202a9ca66978136d74880193a409db0587ce2e0aecb1df2f2f9d9296de6747117b
7
- data.tar.gz: 71f1c9ee7fed6e38ee4eee06d03f9f8da39d64c4cb64999a5d1135a59d4a03080a77dcc8c7f327eb9d4f6faa355bf4c3b13f2ab83bdb4e6f422e260e5fe77f8d
6
+ metadata.gz: c9db109456c8ef386aff44f28160b9e5988055ec3e71a5f0e8e8c9133a4effbc805bc77c3992aab55b9caa98db306a29aca056866a8ce9cc7301c6eda1b327c9
7
+ data.tar.gz: b9c2c04281e7fc4eadb4e9760f9eae5c5b6a6394f038326995824c353c11bbb96de3a1fefdf9f3843e6ce39683f0854fc5693d5c70fc8cc3967abd5c9fe8a7ad
@@ -299,7 +299,7 @@ module Webspicy
299
299
  # truthy value is returned will be considered by the scope.
300
300
  # - ===: any instance responding to `===` can be used as a matcher, following
301
301
  # Ruby conventions. The match is done on a Service instance.
302
- def test_case_filter=(tag_filter)
302
+ def test_case_filter=(test_case_filter)
303
303
  @test_case_filter = test_case_filter
304
304
  end
305
305
  attr_reader :test_case_filter
@@ -2,6 +2,7 @@ module Webspicy
2
2
  class Specification
3
3
  module Postcondition
4
4
  class MissingConditionImpl
5
+ include Pre
5
6
  include Post
6
7
 
7
8
  def check!
@@ -2,6 +2,7 @@ module Webspicy
2
2
  class Specification
3
3
  module Postcondition
4
4
  class UnexpectedConditionImpl
5
+ include Pre
5
6
  include Post
6
7
 
7
8
  def check!
@@ -149,7 +149,7 @@ module Webspicy
149
149
  mc.matching_description = d
150
150
  }
151
151
  }
152
- mapped + unmapped + unexpected
152
+ instances + unmapped + unexpected
153
153
  end
154
154
 
155
155
  def bind_examples
@@ -1,49 +1,69 @@
1
1
  module Webspicy
2
2
  module Support
3
3
  class DeepMerge
4
- class << self
5
4
 
6
- def symbolize_keys(arg)
7
- case arg
8
- when Hash
9
- arg.each_pair.each_with_object({}){|(k,v),memo|
10
- memo[k.to_sym] = symbolize_keys(v)
11
- }
12
- when Array
13
- arg.map{|item| symbolize_keys(item) }
14
- else
15
- arg
16
- end
17
- end
5
+ DEFAULT_OPTIONS = {
6
+ uniq_on_arrays: false
7
+ }
8
+
9
+ def initialize(options = {})
10
+ @options = DEFAULT_OPTIONS.merge(options)
11
+ end
12
+
13
+ def self.deep_merge(*args, &bl)
14
+ new.deep_merge(*args, &bl)
15
+ end
16
+
17
+ def self.deep_dup(*args, &bl)
18
+ new.deep_dup(*args, &bl)
19
+ end
20
+
21
+ def self.symbolize_keys(*args, &bl)
22
+ new.symbolize_keys(*args, &bl)
23
+ end
18
24
 
19
- def deep_merge(h1, h2)
20
- merge_maps(deep_dup(h1), deep_dup(h2))
25
+ def symbolize_keys(arg)
26
+ case arg
27
+ when Hash
28
+ arg.each_pair.each_with_object({}){|(k,v),memo|
29
+ memo[k.to_sym] = symbolize_keys(v)
30
+ }
31
+ when Array
32
+ arg.map{|item| symbolize_keys(item) }
33
+ else
34
+ arg
21
35
  end
36
+ end
22
37
 
23
- def deep_dup(x)
24
- case x
25
- when Array
26
- x.map{|y| deep_dup(y) }
27
- when Hash
28
- x.each_with_object({}){|(k,v),memo| memo[k] = deep_dup(v) }
29
- else
30
- x
31
- end
38
+ def deep_merge(h1, h2)
39
+ merge_maps(deep_dup(h1), deep_dup(h2))
40
+ end
41
+
42
+ def deep_dup(x)
43
+ case x
44
+ when Array
45
+ x.map{|y| deep_dup(y) }
46
+ when Hash
47
+ x.each_with_object({}){|(k,v),memo| memo[k] = deep_dup(v) }
48
+ else
49
+ x
32
50
  end
51
+ end
33
52
 
34
- private
53
+ private
35
54
 
36
- def merge_maps(h1, h2)
37
- h1.merge(h2) do |k,v1,v2|
38
- case v1
39
- when Hash then merge_maps(v1, v2)
40
- when Array then v1 + v2
41
- else v2
42
- end
55
+ def merge_maps(h1, h2)
56
+ h1.merge(h2) do |k,v1,v2|
57
+ case v1
58
+ when Hash
59
+ merge_maps(v1, v2)
60
+ when Array
61
+ @options[:uniq_on_arrays] ? (v1 + v2).uniq : v1 + v2
62
+ else v2
43
63
  end
44
64
  end
45
-
46
65
  end
66
+
47
67
  end
48
68
  end
49
69
  end
@@ -12,8 +12,11 @@ module Webspicy
12
12
  end
13
13
 
14
14
  def call
15
- return unless invocation.is_structured_output?
16
- output = invocation.loaded_body
15
+ output = if invocation.is_structured_output?
16
+ invocation.loaded_body
17
+ else
18
+ invocation.raw_output
19
+ end
17
20
  service.error_schema.dress(output)
18
21
  rescue Finitio::TypeError => ex
19
22
  _! "Invalid error: #{ex.message}"
@@ -12,8 +12,11 @@ module Webspicy
12
12
  end
13
13
 
14
14
  def call
15
- return unless invocation.is_structured_output?
16
- output = invocation.loaded_body
15
+ output = if invocation.is_structured_output?
16
+ invocation.loaded_body
17
+ else
18
+ invocation.raw_output
19
+ end
17
20
  service.output_schema.dress(output)
18
21
  rescue Finitio::TypeError => ex
19
22
  _! "Invalid output: #{ex.message}"
@@ -65,7 +65,11 @@ module Webspicy
65
65
  raise Error, "No such service `#{method} #{url}`"
66
66
  end
67
67
  mutated = tc.mutate(mutation)
68
- fork_tester(test_case: mutated) do |t|
68
+ call_one(mutated)
69
+ end
70
+
71
+ def call_one(test_case)
72
+ fork_tester(test_case: test_case) do |t|
69
73
  instrumented = t.instrument_test_case
70
74
  t.client.call(instrumented)
71
75
  end
@@ -1,7 +1,7 @@
1
1
  module Webspicy
2
2
  module Version
3
3
  MAJOR = 0
4
- MINOR = 25
4
+ MINOR = 27
5
5
  TINY = 0
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
@@ -11,10 +11,16 @@ FileUpload =
11
11
  param_name :? String
12
12
  }
13
13
 
14
+ OpenApi = {
15
+ tag :? String
16
+ summary :? String
17
+ }
18
+
14
19
  Specification = .Webspicy::Web::Specification
15
20
  <info> {
16
21
  name: String
17
22
  url: String
23
+ openapi :? OpenApi
18
24
  services: [Service]
19
25
  }
20
26
  <singleservice> {
@@ -22,6 +28,7 @@ Specification = .Webspicy::Web::Specification
22
28
  url : String
23
29
  method : Method
24
30
  description : String
31
+ openapi :? OpenApi
25
32
  preconditions :? [String]|String
26
33
  postconditions :? [String]|String
27
34
  errconditions :? [String]|String
@@ -39,6 +46,7 @@ Service =
39
46
  name :? String
40
47
  method : Method
41
48
  description : String
49
+ openapi :? OpenApi
42
50
  preconditions :? [String]|String
43
51
  postconditions :? [String]|String
44
52
  errconditions :? [String]|String
@@ -51,8 +59,30 @@ Service =
51
59
  counterexamples :? [TestCase]
52
60
  }
53
61
 
54
- TestCase =
55
- .Webspicy::Web::Specification::TestCase <info> {
62
+ TestCase = .Webspicy::Web::Specification::TestCase
63
+ <v2> {
64
+ for :? String
65
+ when :? String
66
+ it :? String
67
+ description :? String
68
+ validate_input :? Boolean
69
+ input :? Params
70
+ headers :? .Hash
71
+ body :? String
72
+ file_upload :? FileUpload
73
+ seeds :? String
74
+ requester :? String
75
+ metadata :? { ...: .Object }
76
+ expected :? {
77
+ status :? StatusRange
78
+ content_type :? String|Nil
79
+ error :? String
80
+ headers :? .Hash
81
+ }
82
+ assert :? [String]
83
+ tags :? [Tag]
84
+ }
85
+ <info> {
56
86
  description :? String
57
87
  dress_params :? Boolean
58
88
  params :? Params
@@ -0,0 +1,40 @@
1
+ module Webspicy
2
+ module Web
3
+ module Openapi
4
+ class DataStruct
5
+
6
+ MERGER = Support::DeepMerge.new({
7
+ uniq_on_arrays: true
8
+ })
9
+
10
+ def initialize
11
+ @info = {}
12
+ @tags = []
13
+ @paths = {}
14
+ end
15
+ attr_reader :info, :tags, :paths
16
+
17
+ def ensure_tags(tags)
18
+ @tags = (@tags + tags).uniq.sort_by{|t| t[:name] }
19
+ end
20
+
21
+ def ensure_path(path)
22
+ @paths = MERGER.deep_merge(
23
+ @paths,
24
+ path,
25
+ )
26
+ end
27
+
28
+ def to_openapi_data
29
+ {
30
+ "openapi" => '3.0.2',
31
+ "info" => info,
32
+ "tags" => tags,
33
+ "paths" => paths,
34
+ }
35
+ end
36
+
37
+ end # class DataStruct
38
+ end # module Openapi
39
+ end # module Web
40
+ end # module Webspicy
@@ -0,0 +1,36 @@
1
+ module Webspicy
2
+ module Web
3
+ module Openapi
4
+ class Reporter < Webspicy::Tester::Reporter
5
+ include Utils
6
+
7
+ def initialize(base, output_file)
8
+ @base = base
9
+ @output_file = output_file
10
+ end
11
+
12
+ def before_all
13
+ @datastruct = DataStruct.new
14
+ end
15
+
16
+ def after_each
17
+ @datastruct.ensure_tags(tags_for(specification))
18
+ @datastruct.ensure_path(base_path_for(specification))
19
+ @datastruct.ensure_path(base_verb_for(service))
20
+ @datastruct.ensure_path(base_request_body_for(service))
21
+ @datastruct.ensure_path(base_request_example_for(test_case))
22
+ @datastruct.ensure_path(base_request_response_for(invocation))
23
+ end
24
+
25
+ def report
26
+ json = Support::DeepMerge.deep_merge(
27
+ @base,
28
+ @datastruct.to_openapi_data,
29
+ )
30
+ @output_file.write(JSON.pretty_generate(json))
31
+ end
32
+
33
+ end # class Reporter
34
+ end # class OpenApi
35
+ end # class Web
36
+ end # module Webspicy
@@ -0,0 +1,210 @@
1
+ module Webspicy
2
+ module Web
3
+ module Openapi
4
+ module Utils
5
+
6
+ def into_specification_path(specification, x)
7
+ {
8
+ standardize(specification.url) => x.compact,
9
+ }
10
+ end
11
+
12
+ def into_service_verb(service, x)
13
+ verb = downcase_verb(service)
14
+ into_specification_path(service.specification, {
15
+ verb => x.compact,
16
+ })
17
+ end
18
+
19
+ def into_service_request_body(service, x)
20
+ into_service_verb(service, {
21
+ requestBody: x.compact,
22
+ })
23
+ end
24
+
25
+ def into_service_responses(service, x)
26
+ into_service_verb(service, {
27
+ responses: x.compact,
28
+ })
29
+ end
30
+
31
+ ###
32
+
33
+ def base_path_for(specification)
34
+ into_specification_path(specification, {
35
+ summary: specification.name.to_s || 'API Specification'
36
+ })
37
+ end
38
+
39
+ def base_verb_for(service)
40
+ verb_defn = {
41
+ summary: service.name,
42
+ description: service.description,
43
+ tags: tags_for(service.specification).map{|s| s[:name] },
44
+ parameters: parameters_for(service),
45
+ }
46
+
47
+ verb_defn = service.conditions.inject(verb_defn) do |memo, p|
48
+ if p.respond_to?(:contribute_to_openapi_verb)
49
+ p.contribute_to_openapi_verb(memo)
50
+ else
51
+ memo
52
+ end
53
+ end
54
+
55
+ into_service_verb(service, verb_defn)
56
+ end
57
+
58
+ def extract_request_body_info_for(service)
59
+ verb = downcase_verb(service)
60
+ return nil if ['get', 'options', 'head'].include?(verb)
61
+
62
+ schema = actual_body_schema(service)
63
+ return nil if empty_schema?(schema)
64
+ puts schema.inspect
65
+
66
+ content_type = content_type_for(service)
67
+
68
+ [schema, content_type]
69
+ end
70
+
71
+ def base_request_body_for(service)
72
+ schema, content_type = extract_request_body_info_for(service)
73
+ return {} unless schema
74
+
75
+ into_service_request_body(service, {
76
+ required: true,
77
+ content: {
78
+ content_type => {
79
+ schema: schema.to_json_schema,
80
+ }.compact,
81
+ },
82
+ })
83
+ end
84
+
85
+ def base_request_example_for(test_case)
86
+ schema, content_type = extract_request_body_info_for(service)
87
+ return {} unless schema
88
+
89
+ value = test_case.params
90
+ in_url = service.specification.url_placeholders
91
+ value = value.reject{|k,v| in_url.include?(k) } if value.is_a?(Hash)
92
+
93
+ example = {
94
+ description: test_case.description,
95
+ value: value,
96
+ }
97
+
98
+ into_service_request_body(service, {
99
+ required: true,
100
+ content: {
101
+ content_type => {
102
+ examples: {
103
+ test_case.description => example
104
+ }
105
+ }.compact,
106
+ },
107
+ })
108
+ end
109
+
110
+ def base_request_response_for(invocation)
111
+ test_case = invocation.test_case
112
+ service = invocation.service
113
+ content_type = content_type_for(service)
114
+ verb = downcase_verb(service)
115
+
116
+ content = nil
117
+ unless invocation.is_empty_response?
118
+ schema = actual_output_schema(test_case, false)
119
+ example = invocation.loaded_output
120
+ content = {
121
+ content_type => {
122
+ schema: schema&.to_json_schema,
123
+ example: example,
124
+ }.compact
125
+ }
126
+ end
127
+
128
+ into_service_responses(service, {
129
+ invocation.response_code.to_s => {
130
+ description: '',
131
+ content: content,
132
+ }.compact
133
+ })
134
+ end
135
+
136
+ def tags_for(specification)
137
+ tag = specification&.openapi&.[](:tag) || specification.name
138
+
139
+ return [] unless tag.is_a?(String)
140
+ return [] if tag.empty?
141
+
142
+ [{
143
+ name: tag.gsub(/\n/, ' ').strip
144
+ }]
145
+ end
146
+
147
+ def parameters_for(service)
148
+ schema = actual_input_schema(service)
149
+ params = service.specification.url_placeholders.map{|p|
150
+ {
151
+ in: 'path',
152
+ name: p,
153
+ schema: { type: 'string' },
154
+ required: true
155
+ }
156
+ }
157
+ params.empty? ? nil : params
158
+ end
159
+
160
+ def actual_output_schema(test_case, counterexample)
161
+ if counterexample
162
+ test_case.service.error_schema['Main']
163
+ else
164
+ test_case.service.output_schema['Main']
165
+ end
166
+ end
167
+
168
+ def actual_input_schema(service)
169
+ service.input_schema['Main']
170
+ end
171
+
172
+ def actual_body_schema(service)
173
+ schema = actual_input_schema(service)
174
+
175
+ a_schema = schema
176
+ a_schema = schema.target if schema.is_a?(Finitio::AliasType)
177
+ return schema unless a_schema.is_a?(Finitio::HashBasedType)
178
+
179
+ in_url = service.specification.url_placeholders.map(&:to_sym)
180
+ return schema if in_url.empty?
181
+
182
+ a_schema.allbut(in_url)
183
+ end
184
+
185
+ def standardize(url)
186
+ url = url.gsub(/\/$/, '') if url =~ /\/$/
187
+ url
188
+ end
189
+
190
+ def downcase_verb(service)
191
+ service.method.downcase.gsub(/_form$/, '')
192
+ end
193
+
194
+ def content_type_for(service)
195
+ if service.method.downcase == 'post_form'
196
+ 'application/x-www-form-urlencoded'
197
+ else
198
+ 'application/json'
199
+ end
200
+ end
201
+
202
+ def empty_schema?(schema)
203
+ schema = schema.target if schema.is_a?(Finitio::AliasType)
204
+ schema.is_a?(Finitio::HashBasedType) && schema.heading.empty?
205
+ end
206
+
207
+ end # module Utils
208
+ end # module Openapi
209
+ end # module Web
210
+ end # module Webspicy
@@ -1,2 +1,5 @@
1
+ require_relative 'openapi/utils'
2
+ require_relative 'openapi/data_struct'
3
+ require_relative 'openapi/reporter'
1
4
  require_relative 'openapi/generator'
2
5
  require_relative 'openapi/ext'
@@ -27,7 +27,6 @@ module Webspicy
27
27
  extra = headers.reject{|k|
28
28
  test_case.headers.has_key?(k)
29
29
  }
30
- puts "Instrumenting #{test_case.object_id}"
31
30
  test_case.headers.merge!(extra)
32
31
  end
33
32
 
@@ -3,6 +3,24 @@ module Webspicy
3
3
  class Specification
4
4
  class TestCase < Webspicy::Specification::TestCase
5
5
 
6
+ def self.v2(info)
7
+ info = info.dup
8
+ if !info.has_key?(:description) && (info.has_key?(:when) || info.has_key?(:it))
9
+ info[:description] = "when #{info[:when]}" if info.has_key?(:when)
10
+ info[:description] << ", it #{info[:it]}" if info.has_key?(:it)
11
+ info.delete_if{|k,v| k == :when || k == :it }
12
+ end
13
+ if !info.has_key?(:dress_params) && info.has_key?(:validate_input)
14
+ info[:dress_params] = info[:validate_input]
15
+ info.delete(:validate_input)
16
+ end
17
+ if !info.has_key?(:params) && info.has_key?(:input)
18
+ info[:params] = info[:input]
19
+ info.delete(:input)
20
+ end
21
+ new(info)
22
+ end
23
+
6
24
  def headers
7
25
  @raw[:headers] ||= {}
8
26
  end
@@ -52,6 +70,20 @@ module Webspicy
52
70
  !expected_headers.empty?
53
71
  end
54
72
 
73
+ def to_v2
74
+ info = to_info
75
+ info = info.merge({
76
+ validate_input: !!info[:dress_params],
77
+ input: info[:params] || {},
78
+ }).delete_if{|k,v| k == :dress_params || k == :params }
79
+ if info[:description] =~ /^when (.*?), it (.*)$/
80
+ info[:when] = $1
81
+ info[:it] = $2
82
+ info.delete(:description)
83
+ end
84
+ info
85
+ end
86
+
55
87
  end # class TestCase
56
88
  end # class Specification
57
89
  end # module Web
@@ -19,6 +19,10 @@ module Webspicy
19
19
  end
20
20
  end
21
21
 
22
+ def openapi
23
+ @raw[:openapi]
24
+ end
25
+
22
26
  def url
23
27
  @raw[:url]
24
28
  end
@@ -52,7 +52,7 @@ module Webspicy
52
52
  let(:example) {
53
53
  Webspicy::Web.test_case({
54
54
  description: "Hello world",
55
- expected: { content_type: "application/json" }
55
+ expected: { content_type: "application/json" },
56
56
  })
57
57
  }
58
58
 
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+ module Webspicy
3
+ module Web
4
+ class Specification
5
+ describe TestCase, "v2 information contract" do
6
+
7
+ it 'dresses fine' do
8
+ tc = Webspicy::Web.test_case({
9
+ when: "a condition",
10
+ it: "does something",
11
+ input: { foo: "bar" },
12
+ validate_input: false,
13
+ })
14
+ expect(tc.description).to eql("when a condition, it does something")
15
+ expect(tc.params).to eql({ foo: "bar" })
16
+ expect(tc.dress_params).to eql(false)
17
+ end
18
+
19
+ it 'undresses fine' do
20
+ tc = Webspicy::Web.test_case({
21
+ when: "a condition",
22
+ it: "does something",
23
+ input: { foo: "bar" },
24
+ validate_input: false,
25
+ })
26
+ expect(tc.to_v2).to eql({
27
+ when: "a condition",
28
+ it: "does something",
29
+ input: { foo: "bar" },
30
+ validate_input: false,
31
+ })
32
+ end
33
+
34
+ it 'keeps to_info clean' do
35
+ tc = Webspicy::Web.test_case({
36
+ when: "a condition",
37
+ it: "does something",
38
+ input: { foo: "bar" },
39
+ validate_input: false,
40
+ })
41
+ expect(tc.to_info).to eql({
42
+ description: "when a condition, it does something",
43
+ params: { foo: "bar" },
44
+ dress_params: false,
45
+ })
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
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.25.0
4
+ version: 0.27.0
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: 2023-06-09 00:00:00.000000000 Z
11
+ date: 2025-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -28,9 +28,9 @@ dependencies:
28
28
  name: sinatra
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - ">"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.2.4
33
+ version: '3.0'
34
34
  - - "<"
35
35
  - !ruby/object:Gem::Version
36
36
  version: '4.0'
@@ -38,9 +38,9 @@ dependencies:
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
- - - ">="
41
+ - - ">"
42
42
  - !ruby/object:Gem::Version
43
- version: 2.2.4
43
+ version: '3.0'
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '4.0'
@@ -62,37 +62,49 @@ dependencies:
62
62
  name: rspec_junit_formatter
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - "~>"
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0.6'
68
+ - - "<"
66
69
  - !ruby/object:Gem::Version
67
- version: 0.4.1
70
+ version: '0.7'
68
71
  type: :development
69
72
  prerelease: false
70
73
  version_requirements: !ruby/object:Gem::Requirement
71
74
  requirements:
72
- - - "~>"
75
+ - - ">="
73
76
  - !ruby/object:Gem::Version
74
- version: 0.4.1
77
+ version: '0.6'
78
+ - - "<"
79
+ - !ruby/object:Gem::Version
80
+ version: '0.7'
75
81
  - !ruby/object:Gem::Dependency
76
82
  name: rack-test
77
83
  requirement: !ruby/object:Gem::Requirement
78
84
  requirements:
79
- - - "~>"
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '2.0'
88
+ - - "<"
80
89
  - !ruby/object:Gem::Version
81
- version: 0.6.3
90
+ version: '3.0'
82
91
  type: :runtime
83
92
  prerelease: false
84
93
  version_requirements: !ruby/object:Gem::Requirement
85
94
  requirements:
86
- - - "~>"
95
+ - - ">="
87
96
  - !ruby/object:Gem::Version
88
- version: 0.6.3
97
+ version: '2.0'
98
+ - - "<"
99
+ - !ruby/object:Gem::Version
100
+ version: '3.0'
89
101
  - !ruby/object:Gem::Dependency
90
102
  name: finitio
91
103
  requirement: !ruby/object:Gem::Requirement
92
104
  requirements:
93
105
  - - ">="
94
106
  - !ruby/object:Gem::Version
95
- version: 0.12.0
107
+ version: 0.12.2
96
108
  - - "<"
97
109
  - !ruby/object:Gem::Version
98
110
  version: 0.13.0
@@ -102,7 +114,7 @@ dependencies:
102
114
  requirements:
103
115
  - - ">="
104
116
  - !ruby/object:Gem::Version
105
- version: 0.12.0
117
+ version: 0.12.2
106
118
  - - "<"
107
119
  - !ruby/object:Gem::Version
108
120
  version: 0.13.0
@@ -110,16 +122,22 @@ dependencies:
110
122
  name: http
111
123
  requirement: !ruby/object:Gem::Requirement
112
124
  requirements:
113
- - - "~>"
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '5.0'
128
+ - - "<"
114
129
  - !ruby/object:Gem::Version
115
- version: 4.4.1
130
+ version: '6.0'
116
131
  type: :runtime
117
132
  prerelease: false
118
133
  version_requirements: !ruby/object:Gem::Requirement
119
134
  requirements:
120
- - - "~>"
135
+ - - ">="
121
136
  - !ruby/object:Gem::Version
122
- version: 4.4.1
137
+ version: '5.0'
138
+ - - "<"
139
+ - !ruby/object:Gem::Version
140
+ version: '6.0'
123
141
  - !ruby/object:Gem::Dependency
124
142
  name: path
125
143
  requirement: !ruby/object:Gem::Requirement
@@ -200,16 +218,22 @@ dependencies:
200
218
  name: openapi3_parser
201
219
  requirement: !ruby/object:Gem::Requirement
202
220
  requirements:
203
- - - "~>"
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ version: '0.9'
224
+ - - "<"
204
225
  - !ruby/object:Gem::Version
205
- version: 0.8.2
226
+ version: '0.10'
206
227
  type: :runtime
207
228
  prerelease: false
208
229
  version_requirements: !ruby/object:Gem::Requirement
209
230
  requirements:
210
- - - "~>"
231
+ - - ">="
232
+ - !ruby/object:Gem::Version
233
+ version: '0.9'
234
+ - - "<"
211
235
  - !ruby/object:Gem::Version
212
- version: 0.8.2
236
+ version: '0.10'
213
237
  - !ruby/object:Gem::Dependency
214
238
  name: mustache
215
239
  requirement: !ruby/object:Gem::Requirement
@@ -375,8 +399,11 @@ files:
375
399
  - lib/webspicy/web/mocker.rb
376
400
  - lib/webspicy/web/mocker/config.ru
377
401
  - lib/webspicy/web/openapi.rb
402
+ - lib/webspicy/web/openapi/data_struct.rb
378
403
  - lib/webspicy/web/openapi/ext.rb
379
404
  - lib/webspicy/web/openapi/generator.rb
405
+ - lib/webspicy/web/openapi/reporter.rb
406
+ - lib/webspicy/web/openapi/utils.rb
380
407
  - lib/webspicy/web/specification.rb
381
408
  - lib/webspicy/web/specification/file_upload.rb
382
409
  - lib/webspicy/web/specification/post.rb
@@ -417,6 +444,7 @@ files:
417
444
  - spec/unit/web/mocker/test_mocker.rb
418
445
  - spec/unit/web/openapi/test_generator.rb
419
446
  - spec/unit/web/specification/pre/test_global_request_headers.rb
447
+ - spec/unit/web/specification/test_case/test_v2_ic.rb
420
448
  - spec/unit/web/specification/test_instantiate_url.rb
421
449
  - spec/unit/web/specification/test_url_placeholders.rb
422
450
  - tasks/gem.rake
@@ -425,7 +453,7 @@ homepage: http://github.com/enspirit/webspicy
425
453
  licenses:
426
454
  - MIT
427
455
  metadata: {}
428
- post_install_message:
456
+ post_install_message:
429
457
  rdoc_options: []
430
458
  require_paths:
431
459
  - lib
@@ -440,8 +468,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
440
468
  - !ruby/object:Gem::Version
441
469
  version: '0'
442
470
  requirements: []
443
- rubygems_version: 3.3.26
444
- signing_key:
471
+ rubygems_version: 3.3.27
472
+ signing_key:
445
473
  specification_version: 4
446
474
  summary: Webspicy helps testing web services as software operation black boxes!
447
475
  test_files: []