sinatra-swagger-exposer 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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