sinatra-swagger-exposer 0.3.0 → 0.4.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/Gemfile +0 -1
  4. data/README.md +1 -0
  5. data/lib/sinatra/swagger-exposer/configuration/swagger-configuration-utilities.rb +124 -0
  6. data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint-parameter.rb +15 -20
  7. data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint-response.rb +39 -7
  8. data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint.rb +21 -8
  9. data/lib/sinatra/swagger-exposer/configuration/swagger-hash-like.rb +45 -0
  10. data/lib/sinatra/swagger-exposer/configuration/swagger-info.rb +9 -8
  11. data/lib/sinatra/swagger-exposer/configuration/swagger-response-header.rb +68 -0
  12. data/lib/sinatra/swagger-exposer/configuration/swagger-response-headers.rb +33 -0
  13. data/lib/sinatra/swagger-exposer/configuration/swagger-type-property.rb +7 -6
  14. data/lib/sinatra/swagger-exposer/configuration/swagger-type.rb +10 -9
  15. data/lib/sinatra/swagger-exposer/configuration/swagger-types.rb +4 -20
  16. data/lib/sinatra/swagger-exposer/processing/swagger-array-value-processor.rb +46 -0
  17. data/lib/sinatra/swagger-exposer/processing/{swagger-base-value-preprocessor.rb → swagger-base-value-processor.rb} +9 -7
  18. data/lib/sinatra/swagger-exposer/processing/{swagger-parameter-preprocessor.rb → swagger-parameter-processor.rb} +9 -9
  19. data/lib/sinatra/swagger-exposer/processing/{swagger-primitive-value-preprocessor.rb → swagger-primitive-value-processor.rb} +46 -46
  20. data/lib/sinatra/swagger-exposer/processing/{swagger-preprocessor-dispatcher.rb → swagger-processor-dispatcher.rb} +11 -11
  21. data/lib/sinatra/swagger-exposer/processing/swagger-request-processor.rb +123 -0
  22. data/lib/sinatra/swagger-exposer/processing/swagger-response-processor.rb +47 -0
  23. data/lib/sinatra/swagger-exposer/processing/swagger-type-value-processor.rb +37 -0
  24. data/lib/sinatra/swagger-exposer/swagger-content-creator.rb +3 -7
  25. data/lib/sinatra/swagger-exposer/swagger-exposer.rb +99 -33
  26. data/lib/sinatra/swagger-exposer/swagger-parameter-helper.rb +19 -19
  27. data/lib/sinatra/swagger-exposer/swagger-request-processor-creator.rb +180 -0
  28. data/lib/sinatra/swagger-exposer/version.rb +1 -1
  29. data/sinatra-swagger-exposer.gemspec +9 -8
  30. metadata +29 -11
  31. data/lib/sinatra/swagger-exposer/processing/swagger-array-value-preprocessor.rb +0 -46
  32. data/lib/sinatra/swagger-exposer/processing/swagger-request-preprocessor.rb +0 -64
  33. data/lib/sinatra/swagger-exposer/processing/swagger-type-value-preprocessor.rb +0 -37
  34. data/lib/sinatra/swagger-exposer/swagger-preprocessor-creator.rb +0 -137
  35. data/lib/sinatra/swagger-exposer/swagger-utilities.rb +0 -108
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5aed90279990c755b73bdd72cada6ffa5437050f
4
- data.tar.gz: b11db6f75e29d6bce33a8f158e960754a2f94289
3
+ metadata.gz: 99783f615757c81a5f32093c96bc4e6c8daca8ca
4
+ data.tar.gz: 48bfb098f71405d8d75c800dba55108fa453db29
5
5
  SHA512:
6
- metadata.gz: 79b57a8f5ddeb0c8d7cc8503550f5393274eec14527a1d5c23c5e123e8b6320a97b952b0945a0107e77ba143f82caaac4aa7c5106e5e39368c5d098872c1407d
7
- data.tar.gz: 1a2fe99a4e7c6fd264023c952dfab82abd07f2a58f6009e1c933aa9179cf980c38f5997f860ed76d5265397a4bbf814eeede16ddff87fbabcb4a2ffb575a6e07
6
+ metadata.gz: ef40b1896dc2f5f12ba702620d469868698b427d29d4600014a5804eb1dca682aa197e0f14287fde1d9f2b962dce7acfd3ef5b0b6596b0a46c35f2a5147bd37d
7
+ data.tar.gz: a5a48f8e4a46fece4af4a015fe87e77c9ca12bedc4822f32a306247c323dfe9a4c0f3e6491fb755058fcf741cfe89d876c3741699cafcaa093570b918285c848
@@ -1,4 +1,11 @@
1
+ # 0.4.0
2
+
3
+ - Validate responses
4
+ - No validation when the parameter is null
5
+ - Accept :no_swagger param in declaration
6
+
1
7
  # 0.3.0
8
+
2
9
  - Can now accept types as parameters
3
10
  - Accept json utf-8 content type
4
11
 
data/Gemfile CHANGED
@@ -1,6 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in sinatra-swagger-exposer.gemspec
4
3
  gemspec
5
4
 
6
5
  gem 'codeclimate-test-reporter', group: :test, require: nil
data/README.md CHANGED
@@ -10,6 +10,7 @@ This Sinatra extension enable you to add metadata to your code to
10
10
 
11
11
  - expose your API as a [Swagger](http://swagger.io) endpoint.
12
12
  - validate and enrich the invocation parameters
13
+ - validate the responses during test dans development
13
14
 
14
15
  I'm adding features as I need them and it currently doesn't use all the Swagger options, so if you need one that is missing please open an issue.
15
16
 
@@ -0,0 +1,124 @@
1
+ require_relative '../swagger-invalid-exception'
2
+ require_relative '../swagger-parameter-helper'
3
+
4
+ module Sinatra
5
+
6
+ module SwaggerExposer
7
+
8
+ module Configuration
9
+
10
+ module SwaggerConfigurationUtilities
11
+
12
+ include ::Sinatra::SwaggerExposer::SwaggerParameterHelper
13
+
14
+ def ref_to_type(type)
15
+ {'$ref' => "#/definitions/#{type}"}
16
+ end
17
+
18
+ def hash_to_swagger(hash)
19
+ result = {}
20
+ hash.each_pair do |key, value|
21
+ result[key] = value.to_swagger
22
+ end
23
+ result
24
+ end
25
+
26
+ # Transform a type into a String
27
+ # @return [String]
28
+ def type_to_s(value)
29
+ if [TrueClass, FalseClass].include? value
30
+ TYPE_BOOLEAN
31
+ elsif value == DateTime
32
+ TYPE_DATE_TIME
33
+ elsif value.is_a? Class
34
+ value.to_s.downcase
35
+ else
36
+ value
37
+ end
38
+ end
39
+
40
+ def get_type(type, possible_values)
41
+ @type = type
42
+ if type.nil?
43
+ raise SwaggerInvalidException.new('Type is nil')
44
+ elsif type.is_a?(String) || @type.is_a?(Class)
45
+ @type = type_to_s(@type)
46
+ check_type(@type, possible_values)
47
+ elsif @type.is_a? Array
48
+ @items = type_to_s(get_array_type(@type))
49
+ check_type(@items, possible_values)
50
+ @type = TYPE_ARRAY
51
+ else
52
+ raise SwaggerInvalidException.new("Type [#{@type}] of has an unknown type, should be a class, a string or an array")
53
+ end
54
+ end
55
+
56
+ # Validate if a parameter is in a list of available values
57
+ # @param params [Hash] the parameters
58
+ # @param allowed_values [Enumerable, #include?] the allowed values
59
+ # @param ignored_values [Enumerable, #include?] values to ignore
60
+ # @return [Hash] the filtered hash
61
+ def white_list_params(params, allowed_values, ignored_values = [])
62
+ result = {}
63
+ params.each_pair do |key, value|
64
+ if allowed_values.include? key
65
+ result[key] = value
66
+ elsif !ignored_values.include?(key)
67
+ raise SwaggerInvalidException.new("Unknown property [#{key}] with value [#{value}]#{list_or_none(allowed_values, 'properties')}")
68
+ end
69
+ end
70
+ result
71
+ end
72
+
73
+ def list_or_none(list, name)
74
+ if list.empty?
75
+ ", no available #{name}"
76
+ else
77
+ ", possible #{name} are #{list.join(', ')}"
78
+ end
79
+ end
80
+
81
+ # Validate if a value is suitable for a name
82
+ # @param name [String] the name
83
+ # @return [NilClass]
84
+ def check_name(name)
85
+ unless name.is_a?(String) || name.is_a?(Symbol)
86
+ raise SwaggerInvalidException.new("Name [#{name}] should be a string or a symbol")
87
+ end
88
+ name = name.to_s
89
+ if name.empty?
90
+ raise SwaggerInvalidException.new('Name should not be empty')
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def get_array_type(array)
97
+ if array.empty?
98
+ raise SwaggerInvalidException.new('Type is an empty array, you should specify a type as the array content')
99
+ elsif array.length > 1
100
+ raise SwaggerInvalidException.new("Type [#{array}] has more than one entry, it should only have one")
101
+ else
102
+ type_to_s(array[0])
103
+ end
104
+ end
105
+
106
+ # Validate if a type is in a list of available values
107
+ # @param type [String] the parameter
108
+ # @param allowed_values [Enumerable, #include?] the allowed values
109
+ # @return [NilClass]
110
+ def check_type(type, allowed_values)
111
+ if allowed_values.empty?
112
+ raise SwaggerInvalidException.new("Unknown type [#{type}], no available type")
113
+ elsif !allowed_values.include?(type)
114
+ raise SwaggerInvalidException.new("Unknown type [#{type}]#{list_or_none(allowed_values, 'types')}")
115
+ end
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+
124
+ end
@@ -1,7 +1,8 @@
1
1
  require_relative '../swagger-invalid-exception'
2
- require_relative '../swagger-utilities'
2
+
3
3
  require_relative 'swagger-parameter-validation-helper'
4
4
  require_relative 'swagger-type-property'
5
+ require_relative 'swagger-configuration-utilities'
5
6
 
6
7
  module Sinatra
7
8
 
@@ -11,7 +12,7 @@ module Sinatra
11
12
 
12
13
  class SwaggerEndpointParameter
13
14
 
14
- include Sinatra::SwaggerExposer::SwaggerUtilities
15
+ include SwaggerConfigurationUtilities
15
16
  include SwaggerParameterValidationHelper
16
17
 
17
18
  attr_reader :type, :name, :required, :default, :params, :items, :how_to_pass
@@ -23,15 +24,9 @@ module Sinatra
23
24
  # @param required [TrueClass] if the parameter is required
24
25
  # @param type [String] the type name
25
26
  # @param params [Hash] parameters
26
- # @param known_types [String] know custom types names
27
+ # @param known_types [Array<String>] known custom types names
27
28
  def initialize(name, description, how_to_pass, required, type, params, known_types)
28
- unless name.is_a?(String) || name.is_a?(Symbol)
29
- raise SwaggerInvalidException.new("Name [#{name}] should be a string or a symbol")
30
- end
31
- name = name.to_s
32
- if name.empty?
33
- raise SwaggerInvalidException.new('Name should not be empty')
34
- end
29
+ check_name(name)
35
30
  @name = name
36
31
 
37
32
  if description
@@ -66,9 +61,9 @@ module Sinatra
66
61
  # @return [Hash]
67
62
  def to_swagger
68
63
  result = {
69
- :name => @name,
70
- :in => @how_to_pass,
71
- :required => @required
64
+ :name => @name,
65
+ :in => @how_to_pass,
66
+ :required => @required
72
67
  }
73
68
 
74
69
  if @type
@@ -102,13 +97,13 @@ module Sinatra
102
97
 
103
98
  def to_s
104
99
  {
105
- :name => @name,
106
- :in => @how_to_pass,
107
- :required => @required,
108
- :type => @type,
109
- :items => @items,
110
- :description => @description,
111
- :params => @params,
100
+ :name => @name,
101
+ :in => @how_to_pass,
102
+ :required => @required,
103
+ :type => @type,
104
+ :items => @items,
105
+ :description => @description,
106
+ :params => @params,
112
107
  }.to_json
113
108
  end
114
109
 
@@ -1,6 +1,7 @@
1
- require_relative '../swagger-utilities'
2
1
  require_relative '../swagger-invalid-exception'
3
2
 
3
+ require_relative 'swagger-configuration-utilities'
4
+
4
5
  module Sinatra
5
6
 
6
7
  module SwaggerExposer
@@ -9,15 +10,38 @@ module Sinatra
9
10
 
10
11
  class SwaggerEndpointResponse
11
12
 
12
- include SwaggerUtilities
13
+ include SwaggerConfigurationUtilities
14
+
15
+ attr_reader :type, :items
13
16
 
14
17
  RESPONSE_PRIMITIVES_FILES = PRIMITIVE_TYPES + [TYPE_FILE]
15
18
 
16
- def initialize(type, description, known_types)
17
- get_type(type, known_types + RESPONSE_PRIMITIVES_FILES)
19
+ # @param type the type
20
+ # @param description [String] the description
21
+ # @param known_types [Array<String>] known custom types names
22
+ # @param headers [Array<String] the headers names
23
+ # @param known_headers [Sinatra::SwaggerExposer::Configuration::SwaggerResponseHeaders] the known headers
24
+ def initialize(type, description, known_types, headers, known_headers)
25
+ if type
26
+ get_type(type, known_types + RESPONSE_PRIMITIVES_FILES)
27
+ end
28
+
18
29
  if description
19
30
  @description = description
20
31
  end
32
+
33
+ @headers = {}
34
+ headers.each do |header_name|
35
+ header_name = header_name.to_s
36
+ if @headers.key? header_name
37
+ raise SwaggerInvalidException.new("Duplicated header_name [#{header_name}]")
38
+ end
39
+ unless known_headers.key? header_name
40
+ raise SwaggerInvalidException.new("Unknown header_name [#{header_name}]")
41
+ end
42
+ @headers[header_name] = known_headers[header_name]
43
+ end
44
+
21
45
  end
22
46
 
23
47
  def to_swagger
@@ -47,14 +71,22 @@ module Sinatra
47
71
  result[:description] = @description
48
72
  end
49
73
 
74
+ unless @headers.empty?
75
+ swagged_headers = {}
76
+ @headers.each_pair do |name, value|
77
+ swagged_headers[name] = value.to_swagger
78
+ end
79
+ result[:headers] = swagged_headers
80
+ end
81
+
50
82
  result
51
83
  end
52
84
 
53
85
  def to_s
54
86
  {
55
- :type => @type,
56
- :items => @items,
57
- :description => @description,
87
+ :type => @type,
88
+ :items => @items,
89
+ :description => @description,
58
90
  }.to_json
59
91
  end
60
92
 
@@ -1,5 +1,6 @@
1
1
  require_relative '../swagger-invalid-exception'
2
- require_relative '../swagger-utilities'
2
+
3
+ require_relative 'swagger-configuration-utilities'
3
4
 
4
5
  module Sinatra
5
6
 
@@ -10,16 +11,26 @@ module Sinatra
10
11
  # An endpoint
11
12
  class SwaggerEndpoint
12
13
 
13
- include Sinatra::SwaggerExposer::SwaggerUtilities
14
+ include SwaggerConfigurationUtilities
14
15
 
15
- attr_reader :path, :type, :parameters
16
+ attr_reader :path, :type, :parameters, :responses, :produces
16
17
 
18
+ # @param type [String] the http verb
19
+ # @param sinatra_path [String] the sinatra path
20
+ # @param parameters [Array<Sinatra::SwaggerExposer::Configuration::SwaggerEndpoint>] the endpoint parameters
21
+ # @param responses [Hash<Integer, Sinatra::SwaggerExposer::Configuration::SwaggerEndpointResponse>] the endpoint possible responses
22
+ # @param summary [String] a summary for the endpoint
23
+ # @param description [String] a description for the endpoint
24
+ # @param tags [Array<String>] a list of tags
25
+ # @param explicit_path [String] an explicit path if the sinatra path is a regex
26
+ # @param produces [Array<String>] the result types
17
27
  def initialize(type, sinatra_path, parameters, responses, summary, description, tags, explicit_path, produces)
18
28
  @type = type
19
29
  @path = swagger_path(sinatra_path, explicit_path)
20
30
 
21
31
  @parameters = parameters
22
32
  @responses = responses
33
+ @produces = produces
23
34
 
24
35
  @attributes = {}
25
36
  if summary
@@ -36,6 +47,8 @@ module Sinatra
36
47
  end
37
48
  end
38
49
 
50
+ # Return a swagger version
51
+ # @return [Hash]
39
52
  def to_swagger
40
53
  result = @attributes.clone
41
54
 
@@ -74,11 +87,11 @@ module Sinatra
74
87
 
75
88
  def to_s
76
89
  {
77
- :type => @type,
78
- :path => @path,
79
- :attributes => @attributes,
80
- :parameters => @parameters,
81
- :responses => @responses,
90
+ :type => @type,
91
+ :path => @path,
92
+ :attributes => @attributes,
93
+ :parameters => @parameters,
94
+ :responses => @responses,
82
95
  }.to_json
83
96
  end
84
97
 
@@ -0,0 +1,45 @@
1
+ require_relative '../swagger-invalid-exception'
2
+
3
+ require_relative 'swagger-configuration-utilities'
4
+
5
+ module Sinatra
6
+
7
+ module SwaggerExposer
8
+
9
+ module Configuration
10
+
11
+ # A hash-like for groups of things
12
+ class SwaggerHashLike
13
+
14
+ include SwaggerConfigurationUtilities
15
+
16
+ def initialize(things)
17
+ @things = things
18
+ end
19
+
20
+ def [](name)
21
+ @things[name]
22
+ end
23
+
24
+ def key?(name)
25
+ @things.key? name
26
+ end
27
+
28
+ def check_duplicate(name, type_name)
29
+ if key?(name)
30
+ raise SwaggerInvalidException.new("#{type_name} [#{name}] already exist with value #{@things[name]}")
31
+ end
32
+ end
33
+
34
+ def to_swagger
35
+ if @things.empty?
36
+ nil
37
+ else
38
+ hash_to_swagger(@things)
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,5 +1,6 @@
1
1
  require_relative '../swagger-invalid-exception'
2
- require_relative '../swagger-utilities'
2
+
3
+ require_relative 'swagger-configuration-utilities'
3
4
 
4
5
  module Sinatra
5
6
 
@@ -10,7 +11,7 @@ module Sinatra
10
11
  # The info declaration
11
12
  class SwaggerInfo
12
13
 
13
- include SwaggerUtilities
14
+ include SwaggerConfigurationUtilities
14
15
 
15
16
  def initialize(values)
16
17
  @values = process(values, 'info', INFO_FIELDS, values)
@@ -18,12 +19,12 @@ module Sinatra
18
19
 
19
20
  # Known fields for the info field
20
21
  INFO_FIELDS = {
21
- :version => String,
22
- :title => String,
23
- :description => String,
24
- :termsOfService => String,
25
- :contact => {:name => String, :email => String, :url => String},
26
- :license => {:name => String, :url => String},
22
+ :version => String,
23
+ :title => String,
24
+ :description => String,
25
+ :termsOfService => String,
26
+ :contact => {:name => String, :email => String, :url => String},
27
+ :license => {:name => String, :url => String},
27
28
  }
28
29
 
29
30
  # Recursive function