mini-apivore 0.2.0 → 0.3.1
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/lib/mini_apivore/declarative.rb +24 -19
- data/lib/mini_apivore/fragment.rb +3 -1
- data/lib/mini_apivore/http_codes.rb +3 -1
- data/lib/mini_apivore/swagger.rb +26 -18
- data/lib/mini_apivore/swagger_checker.rb +21 -24
- data/lib/mini_apivore/to_param.rb +81 -67
- data/lib/mini_apivore/validation.rb +59 -50
- data/lib/mini_apivore/version.rb +3 -1
- data/lib/mini_apivore.rb +28 -26
- metadata +26 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55d58253430c43d1c28701361502f0b394e142bb80a4fde28c297b75ca3fc6bf
|
4
|
+
data.tar.gz: 51f6e1590917fb7877956b31a5eb70f334ef433e9e8555720bc2d4fe5749ad72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c494d9d0be4b7632f4a8f4254777e98e57c6d0dc0e3b54e788b8c03ecc251f7956e9b61a918cb246c17b18feef79bc8625fcea4640a397c982f7ef6b7a94401
|
7
|
+
data.tar.gz: cd92cf48901af09e5000793cbce9016453cb8b1e633857039693bac1461c6659c0ad96765cf0c92a37bb8ce0976fdae1b2f8d37b0e6f7621ebedbd07f0f19047
|
@@ -1,26 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "mini_apivore/version"
|
2
4
|
|
3
|
-
|
4
|
-
module
|
5
|
-
module
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
5
|
+
unless defined?(ActiveSupport)
|
6
|
+
module ActiveSupport
|
7
|
+
module Testing
|
8
|
+
module Declarative
|
9
|
+
# Helper to define a test method using a String. Under the hood, it replaces
|
10
|
+
# spaces with underscores and defines the test method.
|
11
|
+
#
|
12
|
+
# test "verify something" do
|
13
|
+
# ...
|
14
|
+
# end
|
15
|
+
def test(name, &block)
|
16
|
+
test_name = "test_#{name.gsub(/\s+/, "_")}".to_sym
|
17
|
+
defined = method_defined?(test_name)
|
18
|
+
raise "#{test_name} is already defined in #{self}" if defined
|
19
|
+
|
20
|
+
if block_given?
|
21
|
+
define_method(test_name, &block)
|
22
|
+
else
|
23
|
+
define_method(test_name) do
|
24
|
+
flunk("No implementation provided for #{name}")
|
25
|
+
end
|
21
26
|
end
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|
25
30
|
end
|
26
|
-
end
|
31
|
+
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "mini_apivore/version"
|
2
4
|
|
3
5
|
module MiniApivore
|
4
6
|
# This is a workaround for json-schema's fragment validation which does not allow paths to contain forward slashes
|
5
7
|
# current json-schema attempts to split('/') on a string path to produce an array.
|
6
8
|
class Fragment < Array
|
7
|
-
def split(
|
9
|
+
def split(_options = nil)
|
8
10
|
self
|
9
11
|
end
|
10
12
|
end
|
data/lib/mini_apivore/swagger.rb
CHANGED
@@ -1,43 +1,51 @@
|
|
1
|
-
|
2
|
-
require 'hashie'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
3
|
+
require "mini_apivore/version"
|
4
|
+
require "hashie"
|
4
5
|
|
5
6
|
module MiniApivore
|
6
|
-
class Swagger <
|
7
|
-
|
7
|
+
class Swagger < Hash
|
8
|
+
include Hashie::Extensions::MergeInitializer
|
9
|
+
include Hashie::Extensions::IndifferentAccess
|
10
|
+
|
11
|
+
NONVERB_PATH_ITEMS = "parameters"
|
8
12
|
|
9
13
|
def validate
|
10
14
|
case version
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
+
when "2.0"
|
16
|
+
schema = File.read(File.expand_path("../../data/swagger_2.0_schema.json", __dir__))
|
17
|
+
else
|
18
|
+
raise "Unknown/unsupported Swagger version to validate against: #{version}"
|
15
19
|
end
|
16
20
|
JSON::Validator.fully_validate(schema, self)
|
17
21
|
end
|
18
22
|
|
19
23
|
def version
|
20
|
-
swagger
|
24
|
+
self["swagger"]
|
21
25
|
end
|
22
26
|
|
23
27
|
def base_path
|
24
|
-
self[
|
28
|
+
self["basePath"] || ""
|
25
29
|
end
|
26
30
|
|
27
31
|
def each_response(&block)
|
28
|
-
paths.each do |path, path_data|
|
29
|
-
next if vendor_specific_tag?
|
32
|
+
self["paths"].each do |path, path_data|
|
33
|
+
next if vendor_specific_tag?(path)
|
34
|
+
|
30
35
|
path_data.each do |verb, method_data|
|
31
36
|
next if NONVERB_PATH_ITEMS.include?(verb)
|
32
|
-
next if vendor_specific_tag?
|
33
|
-
|
37
|
+
next if vendor_specific_tag?(verb)
|
38
|
+
|
39
|
+
if method_data["responses"].nil?
|
34
40
|
raise "No responses found in swagger for path '#{path}', " \
|
35
41
|
"verb #{verb}: #{method_data.inspect}"
|
36
42
|
end
|
37
|
-
method_data
|
43
|
+
method_data["responses"].each do |response_code, response_data|
|
38
44
|
schema_location = nil
|
39
|
-
if response_data
|
40
|
-
schema_location =
|
45
|
+
if response_data["$ref"]
|
46
|
+
schema_location = response_data["$ref"]
|
47
|
+
elsif response_data["schema"]
|
48
|
+
schema_location = Fragment.new(["#", "paths", path, verb, "responses", response_code, "schema"])
|
41
49
|
end
|
42
50
|
block.call(path, verb, response_code, schema_location)
|
43
51
|
end
|
@@ -45,7 +53,7 @@ module MiniApivore
|
|
45
53
|
end
|
46
54
|
end
|
47
55
|
|
48
|
-
def vendor_specific_tag?
|
56
|
+
def vendor_specific_tag?(tag)
|
49
57
|
tag =~ /\Ax-.*/
|
50
58
|
end
|
51
59
|
end
|
@@ -1,23 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "English"
|
1
4
|
require "mini_apivore/version"
|
2
5
|
|
3
6
|
module MiniApivore
|
4
7
|
class SwaggerChecker
|
5
8
|
PATH_TO_CHECKER_MAP = {}
|
6
9
|
|
7
|
-
def self.instance_for(path, schema =
|
10
|
+
def self.instance_for(path, schema = {})
|
8
11
|
PATH_TO_CHECKER_MAP[path] ||= new(path, schema)
|
9
12
|
end
|
10
13
|
|
11
14
|
def has_path?(path)
|
12
|
-
mappings.
|
15
|
+
mappings.key?(path)
|
13
16
|
end
|
14
17
|
|
15
18
|
def has_method_at_path?(path, verb)
|
16
|
-
mappings[path].
|
19
|
+
mappings[path].key?(verb)
|
17
20
|
end
|
18
21
|
|
19
22
|
def has_response_code_for_path?(path, verb, code)
|
20
|
-
mappings[path][verb].
|
23
|
+
mappings[path][verb].key?(code.to_s)
|
21
24
|
end
|
22
25
|
|
23
26
|
def response_codes_for_path(path, verb)
|
@@ -32,18 +35,17 @@ module MiniApivore
|
|
32
35
|
|
33
36
|
def fragment(path, verb, code)
|
34
37
|
path_fragment = mappings[path][verb.to_s][code.to_s]
|
35
|
-
path_fragment
|
38
|
+
path_fragment&.dup
|
36
39
|
end
|
37
40
|
|
38
41
|
def remove_tested_end_point_response(path, verb, code)
|
39
42
|
return if untested_mappings[path].nil? ||
|
40
43
|
untested_mappings[path][verb].nil?
|
44
|
+
|
41
45
|
untested_mappings[path][verb].delete(code.to_s)
|
42
|
-
if untested_mappings[path][verb].size
|
46
|
+
if untested_mappings[path][verb].size.zero?
|
43
47
|
untested_mappings[path].delete(verb)
|
44
|
-
if untested_mappings[path].size
|
45
|
-
untested_mappings.delete(path)
|
46
|
-
end
|
48
|
+
untested_mappings.delete(path) if untested_mappings[path].size.zero?
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
@@ -51,20 +53,14 @@ module MiniApivore
|
|
51
53
|
@swagger.base_path
|
52
54
|
end
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
attr_reader :response, :swagger, :swagger_path
|
59
|
-
|
60
|
-
def untested_mappings; @untested_mappings end
|
61
|
-
def untested_mappings=( other ); @untested_mappings = other end
|
56
|
+
attr_accessor :response, :untested_mappings
|
57
|
+
attr_reader :swagger, :swagger_path
|
62
58
|
|
63
59
|
private
|
64
60
|
|
65
61
|
attr_reader :mappings
|
66
62
|
|
67
|
-
def initialize(swagger_path, schema
|
63
|
+
def initialize(swagger_path, schema)
|
68
64
|
@swagger_path = swagger_path
|
69
65
|
@schema = schema
|
70
66
|
load_swagger_doc!
|
@@ -79,15 +75,15 @@ module MiniApivore
|
|
79
75
|
|
80
76
|
def fetch_swagger!
|
81
77
|
return @schema unless @schema.empty?
|
82
|
-
|
83
|
-
if File.exist?(
|
84
|
-
JSON.parse(
|
78
|
+
|
79
|
+
if File.exist?(swagger_path)
|
80
|
+
JSON.parse(File.read(swagger_path))
|
85
81
|
else
|
86
82
|
session = ActionDispatch::Integration::Session.new(Rails.application)
|
87
83
|
begin
|
88
84
|
session.get(swagger_path)
|
89
|
-
rescue
|
90
|
-
|
85
|
+
rescue StandardError
|
86
|
+
raise "Unable to perform GET request for swagger json: #{swagger_path} - #{$ERROR_INFO}."
|
91
87
|
end
|
92
88
|
JSON.parse(session.response.body)
|
93
89
|
end
|
@@ -98,7 +94,7 @@ module MiniApivore
|
|
98
94
|
unless errors.empty?
|
99
95
|
msg = "The document fails to validate as Swagger #{swagger.version}:\n"
|
100
96
|
msg += errors.join("\n")
|
101
|
-
|
97
|
+
raise msg
|
102
98
|
end
|
103
99
|
end
|
104
100
|
|
@@ -108,6 +104,7 @@ module MiniApivore
|
|
108
104
|
@mappings[path] ||= {}
|
109
105
|
@mappings[path][verb] ||= {}
|
110
106
|
raise "duplicate" unless @mappings[path][verb][response_code].nil?
|
107
|
+
|
111
108
|
@mappings[path][verb][response_code] = fragment
|
112
109
|
end
|
113
110
|
|
@@ -1,84 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "cgi"
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
unless Object.method_defined?(:to_param)
|
6
|
+
class Object
|
7
|
+
# Alias of <tt>to_s</tt>.
|
8
|
+
def to_param
|
9
|
+
to_s
|
10
|
+
end
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
12
|
+
# Converts an object into a string suitable for use as a URL query string,
|
13
|
+
# using the given <tt>key</tt> as the param name.
|
14
|
+
def to_query(key)
|
15
|
+
"#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
|
16
|
+
end
|
13
17
|
end
|
14
|
-
end
|
18
|
+
end
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
unless NilClass.method_defined?(:to_param)
|
21
|
+
class NilClass
|
22
|
+
# Returns +self+.
|
23
|
+
def to_param
|
24
|
+
self
|
25
|
+
end
|
20
26
|
end
|
21
|
-
end
|
27
|
+
end
|
22
28
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
29
|
+
unless TrueClass.method_defined?(:to_param)
|
30
|
+
class TrueClass
|
31
|
+
# Returns +self+.
|
32
|
+
def to_param
|
33
|
+
self
|
34
|
+
end
|
27
35
|
end
|
28
|
-
end
|
36
|
+
end
|
29
37
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
38
|
+
unless FalseClass.method_defined?(:to_param)
|
39
|
+
class FalseClass
|
40
|
+
# Returns +self+.
|
41
|
+
def to_param
|
42
|
+
self
|
43
|
+
end
|
34
44
|
end
|
35
|
-
end
|
45
|
+
end
|
36
46
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
47
|
+
unless Array.method_defined?(:to_param)
|
48
|
+
class Array
|
49
|
+
# Calls <tt>to_param</tt> on all its elements and joins the result with
|
50
|
+
# slashes. This is used by <tt>url_for</tt> in Action Pack.
|
51
|
+
def to_param
|
52
|
+
collect(&:to_param).join("/")
|
53
|
+
end
|
43
54
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
55
|
+
# Converts an array into a string suitable for use as a URL query string,
|
56
|
+
# using the given +key+ as the param name.
|
57
|
+
#
|
58
|
+
# ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding"
|
59
|
+
def to_query(key)
|
60
|
+
prefix = "#{key}[]"
|
50
61
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
62
|
+
if empty?
|
63
|
+
nil.to_query(prefix)
|
64
|
+
else
|
65
|
+
collect { |value| value.to_query(prefix) }.join("&")
|
66
|
+
end
|
55
67
|
end
|
56
68
|
end
|
57
|
-
end
|
69
|
+
end
|
58
70
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
value.
|
79
|
-
|
80
|
-
|
81
|
-
|
71
|
+
unless Hash.method_defined?(:to_param)
|
72
|
+
class Hash
|
73
|
+
# Returns a string representation of the receiver suitable for use as a URL
|
74
|
+
# query string:
|
75
|
+
#
|
76
|
+
# {name: 'David', nationality: 'Danish'}.to_query
|
77
|
+
# # => "name=David&nationality=Danish"
|
78
|
+
#
|
79
|
+
# An optional namespace can be passed to enclose key names:
|
80
|
+
#
|
81
|
+
# {name: 'David', nationality: 'Danish'}.to_query('user')
|
82
|
+
# # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
|
83
|
+
#
|
84
|
+
# The string pairs "key=value" that conform the query string
|
85
|
+
# are sorted lexicographically in ascending order.
|
86
|
+
#
|
87
|
+
# This method is also aliased as +to_param+.
|
88
|
+
def to_query(namespace = nil)
|
89
|
+
collect do |key, value|
|
90
|
+
unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
|
91
|
+
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
92
|
+
end
|
93
|
+
end.compact.sort! * "&"
|
94
|
+
end
|
82
95
|
|
83
|
-
|
84
|
-
end
|
96
|
+
alias_method :to_param, :to_query
|
97
|
+
end
|
98
|
+
end
|
@@ -1,14 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "mini_apivore/version"
|
2
4
|
|
3
5
|
module MiniApivore
|
4
|
-
|
5
|
-
|
6
|
+
# former Validator
|
7
|
+
module Validation
|
6
8
|
class IndHash < Hash
|
7
9
|
include Hashie::Extensions::MergeInitializer
|
8
10
|
include Hashie::Extensions::IndifferentAccess
|
9
11
|
end
|
10
12
|
|
11
|
-
def prepare_action_env(verb, path, expected_response_code, params
|
13
|
+
def prepare_action_env(verb, path, expected_response_code, **params)
|
12
14
|
@errors = []
|
13
15
|
@verb = verb.to_s
|
14
16
|
@path = path.to_s
|
@@ -16,41 +18,45 @@ module MiniApivore
|
|
16
18
|
@expected_response_code = expected_response_code.to_i
|
17
19
|
end
|
18
20
|
|
19
|
-
def swagger_checker
|
21
|
+
def swagger_checker
|
22
|
+
self.class.swagger_checker
|
23
|
+
end
|
20
24
|
|
21
|
-
def check_route(
|
22
|
-
prepare_action_env(
|
23
|
-
assert(
|
25
|
+
def check_route(verb, path, expected_response_code, **params)
|
26
|
+
prepare_action_env(verb, path, expected_response_code, **params)
|
27
|
+
assert(match?, <<FAIL)
|
24
28
|
Failed at: #{prepare_error_backtrace}\n
|
25
|
-
Failure message: #{failure_message},\n
|
26
|
-
fullpath: #{full_path}, \n
|
29
|
+
Failure message: #{failure_message},\n#{" "}
|
30
|
+
fullpath: #{full_path}, \n#{" "}
|
27
31
|
params causing failure:#{params}
|
28
32
|
FAIL
|
29
33
|
end
|
30
34
|
|
31
|
-
|
35
|
+
def prepare_error_backtrace
|
36
|
+
# it will deliver something like this:
|
37
|
+
# "/app/test/helpers/base_routes_helpers.rb:57:in `__create_card'",
|
38
|
+
# "/app/test/integration/cards_api_test.rb:71:in `block (2 levels) in <class:CommentsApiTest>'",
|
39
|
+
Thread.current.backtrace[2..].slice_after { |trc| trc[/check_route/] }.to_a.last[0..1]
|
40
|
+
end
|
32
41
|
|
33
42
|
def match?
|
34
|
-
#pre_checks
|
43
|
+
# pre_checks
|
35
44
|
check_request_path
|
36
45
|
|
37
46
|
# request
|
38
47
|
unless has_errors?
|
39
|
-
|
48
|
+
action_dispatch_request(
|
40
49
|
@verb,
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
headers: @params['_headers'] || {}
|
45
|
-
)
|
50
|
+
full_path,
|
51
|
+
params: @params["_data"] || {},
|
52
|
+
headers: @params["_headers"] || {}
|
46
53
|
)
|
47
54
|
|
48
|
-
#post_checks
|
55
|
+
# post_checks
|
49
56
|
check_status_code
|
50
57
|
check_response_is_valid unless has_errors?
|
51
58
|
|
52
|
-
|
53
|
-
if has_errors? && response.body.length > 0
|
59
|
+
if has_errors? && response.body.length.positive?
|
54
60
|
@errors << "\nResponse body:\n #{JSON.pretty_generate(JSON.parse(response.body))}"
|
55
61
|
end
|
56
62
|
|
@@ -64,19 +70,19 @@ FAIL
|
|
64
70
|
def check_request_path
|
65
71
|
if !swagger_checker.has_path?(@path)
|
66
72
|
@errors << "Swagger doc: #{swagger_checker.swagger_path} does not have"\
|
67
|
-
|
73
|
+
" a documented @path for #{@path}"
|
68
74
|
elsif !swagger_checker.has_method_at_path?(@path, @verb)
|
69
75
|
@errors << "Swagger doc: #{swagger_checker.swagger_path} does not have"\
|
70
|
-
|
76
|
+
" a documented @path for #{@verb} #{@path}"
|
71
77
|
elsif !swagger_checker.has_response_code_for_path?(@path, @verb, @expected_response_code)
|
72
78
|
@errors << "Swagger doc: #{swagger_checker.swagger_path} does not have"\
|
73
|
-
|
74
|
-
|
75
|
-
|
79
|
+
" a documented response code of #{@expected_response_code} at @path"\
|
80
|
+
" #{@verb} #{@path}. "\
|
81
|
+
"\n Available response codes: #{swagger_checker.response_codes_for_path(@path, @verb)}"
|
76
82
|
elsif @verb == "get" && swagger_checker.fragment(@path, @verb, @expected_response_code).nil?
|
77
83
|
@errors << "Swagger doc: #{swagger_checker.swagger_path} missing"\
|
78
|
-
|
79
|
-
|
84
|
+
" response model for get request with #{@path} for code"\
|
85
|
+
" #{@expected_response_code}"
|
80
86
|
end
|
81
87
|
end
|
82
88
|
|
@@ -85,56 +91,59 @@ FAIL
|
|
85
91
|
end
|
86
92
|
|
87
93
|
def apivore_build_path(path, data)
|
88
|
-
path.scan(/\{([
|
94
|
+
path.scan(/\{([^}]*)\}/).each do |param|
|
89
95
|
key = param.first
|
90
|
-
dkey = data && (
|
96
|
+
dkey = data && (data[key] || data[key.to_sym])
|
91
97
|
if dkey
|
92
|
-
path = path.gsub
|
98
|
+
path = path.gsub("{#{key}}", dkey.to_param.to_s)
|
93
99
|
else
|
94
100
|
raise URI::InvalidURIError, "No substitution data found for {#{key}}"\
|
95
|
-
|
101
|
+
" to test the path #{path}.", caller
|
96
102
|
end
|
97
103
|
end
|
98
|
-
path + (data[
|
104
|
+
path + (data["_query_string"] ? "?#{data["_query_string"].to_param}" : "")
|
99
105
|
end
|
100
106
|
|
101
|
-
def has_errors
|
107
|
+
def has_errors?
|
108
|
+
!@errors.empty?
|
109
|
+
end
|
102
110
|
|
103
|
-
def failure_message
|
111
|
+
def failure_message
|
112
|
+
@errors.join(" ")
|
113
|
+
end
|
104
114
|
|
105
115
|
def check_status_code
|
106
116
|
if response.status != @expected_response_code
|
107
117
|
@errors << "Path #{@path} did not respond with expected status code."\
|
108
|
-
|
109
|
-
|
118
|
+
" Expected #{@expected_response_code} got #{response.status}"\
|
119
|
+
end
|
110
120
|
end
|
111
121
|
|
112
122
|
def check_response_is_valid
|
113
123
|
swagger_errors = swagger_checker.has_matching_document_for(
|
114
124
|
@path, @verb, response.status, response_body
|
115
125
|
)
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
126
|
+
return if swagger_errors.empty?
|
127
|
+
|
128
|
+
@errors.concat(
|
129
|
+
swagger_errors.map do |e|
|
130
|
+
e.sub("'#", "'#{full_path}#").gsub(
|
131
|
+
/^The property|in schema.*$/, ""
|
132
|
+
)
|
133
|
+
end
|
134
|
+
)
|
125
135
|
end
|
126
136
|
|
127
137
|
def response_body
|
128
138
|
JSON.parse(response.body) if response.body && !response.body.empty?
|
129
139
|
end
|
130
140
|
|
131
|
-
def
|
141
|
+
def action_dispatch_request(verb, path, params: {}, headers: {})
|
132
142
|
if defined?(ActionPack) && ActionPack::VERSION::MAJOR >= 5
|
133
|
-
|
143
|
+
send(verb, path, params: params, headers: headers)
|
134
144
|
else
|
135
|
-
|
145
|
+
send(verb, path, params, headers)
|
136
146
|
end
|
137
147
|
end
|
138
148
|
end
|
139
|
-
|
140
|
-
end
|
149
|
+
end
|
data/lib/mini_apivore/version.rb
CHANGED
data/lib/mini_apivore.rb
CHANGED
@@ -1,17 +1,24 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json-schema"
|
4
|
+
require "mini_apivore/version"
|
5
|
+
require "mini_apivore/fragment"
|
6
|
+
require "mini_apivore/swagger"
|
7
|
+
require "mini_apivore/swagger_checker"
|
8
|
+
require "mini_apivore/validation"
|
9
|
+
require "mini_apivore/http_codes"
|
10
|
+
require "mini_apivore/to_param"
|
9
11
|
|
10
12
|
module MiniApivore
|
11
13
|
SWAGGER_CHECKERS = {}
|
12
14
|
#----- Module globals -----------------
|
13
|
-
def self.runnable_list
|
14
|
-
|
15
|
+
def self.runnable_list
|
16
|
+
@@runnable_list ||= [] # rubocop:disable Style/ClassVars
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.all_test_ran?
|
20
|
+
runnable_list.empty?
|
21
|
+
end
|
15
22
|
|
16
23
|
def self.prepare_untested_errors
|
17
24
|
errors = []
|
@@ -19,7 +26,7 @@ module MiniApivore
|
|
19
26
|
chkr.untested_mappings.each do |path, methods|
|
20
27
|
methods.each do |method, codes|
|
21
28
|
codes.each do |code, _|
|
22
|
-
errors << "#{method} #{path} is untested for response code #{code} in test class #{cls
|
29
|
+
errors << "#{method} #{path} is untested for response code #{code} in test class #{cls}"
|
23
30
|
end
|
24
31
|
end
|
25
32
|
end
|
@@ -28,26 +35,25 @@ module MiniApivore
|
|
28
35
|
end
|
29
36
|
|
30
37
|
def self.included(base)
|
31
|
-
base.extend
|
32
|
-
base.include
|
38
|
+
base.extend(ClassMethods)
|
39
|
+
base.include(MiniApivore::Validation)
|
33
40
|
end
|
34
41
|
|
35
42
|
#---- class methods -----------
|
36
43
|
module ClassMethods
|
37
|
-
|
38
|
-
def init_swagger( swagger_path, schema= '' )
|
44
|
+
def init_swagger(swagger_path, schema = "")
|
39
45
|
SWAGGER_CHECKERS[self] ||= MiniApivore::SwaggerChecker.instance_for(swagger_path, schema)
|
40
46
|
end
|
41
47
|
|
42
48
|
def runnable_methods
|
43
|
-
super | [
|
49
|
+
super | ["final_test"]
|
44
50
|
end
|
45
51
|
|
46
|
-
def test(name, &block
|
47
|
-
super(
|
52
|
+
def test(name, &block)
|
53
|
+
super(name, &block).tap { |sym| MiniApivore.runnable_list << "#{self}::#{sym}" }
|
48
54
|
end
|
49
55
|
|
50
|
-
def swagger_checker
|
56
|
+
def swagger_checker
|
51
57
|
SWAGGER_CHECKERS[self]
|
52
58
|
end
|
53
59
|
end
|
@@ -55,7 +61,7 @@ module MiniApivore
|
|
55
61
|
#----- Minitest callback -----------
|
56
62
|
def teardown
|
57
63
|
super
|
58
|
-
MiniApivore.runnable_list.delete(
|
64
|
+
MiniApivore.runnable_list.delete("#{self.class}::#{@NAME}")
|
59
65
|
end
|
60
66
|
|
61
67
|
#----- test for untested routes ---------
|
@@ -63,13 +69,9 @@ module MiniApivore
|
|
63
69
|
return unless MiniApivore.all_test_ran?
|
64
70
|
|
65
71
|
@errors = MiniApivore.prepare_untested_errors
|
66
|
-
assert(
|
72
|
+
assert(@errors.empty?, @errors.join("\n"))
|
67
73
|
|
68
74
|
# preventing duplicate execution
|
69
|
-
MiniApivore.runnable_list << "#{self.class
|
75
|
+
MiniApivore.runnable_list << "#{self.class}::#{__method__}_runned"
|
70
76
|
end
|
71
|
-
|
72
|
-
|
73
77
|
end
|
74
|
-
|
75
|
-
|
metadata
CHANGED
@@ -1,57 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mini-apivore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- alekseyl
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: hashie
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '3.3'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '3.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: json-schema
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '5
|
33
|
+
version: '2.5'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '5
|
40
|
+
version: '2.5'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '5.0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '5.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: pry
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 12.3.3
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-shopify
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
description: " Minitest adaptation of apivore gem,\n Provides
|
84
98
|
a tool for testing your application api against your swagger schema "
|
85
99
|
email:
|
@@ -120,8 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
134
|
- !ruby/object:Gem::Version
|
121
135
|
version: '0'
|
122
136
|
requirements: []
|
123
|
-
|
124
|
-
rubygems_version: 2.7.6
|
137
|
+
rubygems_version: 3.2.15
|
125
138
|
signing_key:
|
126
139
|
specification_version: 4
|
127
140
|
summary: Minitest adaptation of an apivore gem
|