skeleton 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +92 -69
  3. data/Rakefile +2 -7
  4. data/lib/skeleton.rb +14 -4
  5. data/lib/skeleton/attributes.rb +19 -0
  6. data/lib/skeleton/config.rb +38 -0
  7. data/lib/skeleton/contact.rb +17 -0
  8. data/lib/skeleton/documentation.rb +17 -0
  9. data/lib/skeleton/example.rb +20 -6
  10. data/lib/skeleton/header.rb +67 -0
  11. data/lib/skeleton/headers.rb +50 -0
  12. data/lib/skeleton/helpers/controller_helpers.rb +25 -0
  13. data/lib/skeleton/info.rb +40 -0
  14. data/lib/skeleton/item.rb +99 -0
  15. data/lib/skeleton/license.rb +16 -0
  16. data/lib/skeleton/model.rb +31 -0
  17. data/lib/skeleton/operation.rb +157 -0
  18. data/lib/skeleton/parameter.rb +100 -20
  19. data/lib/skeleton/path.rb +111 -0
  20. data/lib/skeleton/response.rb +59 -0
  21. data/lib/skeleton/responses.rb +59 -0
  22. data/lib/skeleton/schema.rb +70 -0
  23. data/lib/skeleton/scopes.rb +24 -0
  24. data/lib/skeleton/security_definitions.rb +46 -0
  25. data/lib/skeleton/security_requirement.rb +29 -0
  26. data/lib/skeleton/security_scheme.rb +47 -0
  27. data/lib/skeleton/serializers/swagger.rb +212 -0
  28. data/lib/skeleton/structure.rb +191 -0
  29. data/lib/skeleton/tag.rb +24 -0
  30. data/lib/skeleton/version.rb +1 -1
  31. data/spec/integrations/use_case_spec.rb +130 -0
  32. data/spec/skeleton/operation_spec.rb +113 -0
  33. data/spec/skeleton/serializers/contact_spec.rb +30 -0
  34. data/spec/skeleton/serializers/documentation_spec.rb +23 -0
  35. data/spec/skeleton/serializers/header_spec.rb +57 -0
  36. data/spec/spec_helper.rb +8 -0
  37. metadata +36 -15
  38. data/lib/skeleton/action.rb +0 -46
  39. data/lib/skeleton/builder.rb +0 -47
  40. data/lib/skeleton/link.rb +0 -57
  41. data/spec/skeleton/integrated_spec.rb +0 -38
  42. data/test/skeleton/action_test.rb +0 -78
  43. data/test/skeleton/builder_test.rb +0 -51
  44. data/test/skeleton/link_test.rb +0 -68
  45. data/test/test_helper.rb +0 -6
@@ -0,0 +1,212 @@
1
+ require 'multi_json'
2
+
3
+ module Skeleton
4
+ module Serializers
5
+ class Swagger
6
+ attr_accessor :structure
7
+
8
+ def initialize(args={})
9
+ @structure = args[:structure]
10
+ @version = args[:version] || '2.0'
11
+ end
12
+
13
+ def to_hash
14
+ hash = {
15
+ swagger: @version,
16
+ info: dump_info_to_json(structure.info),
17
+ host: structure.host,
18
+ basePath: structure.base_path,
19
+ schemes: structure.schemes
20
+ }
21
+
22
+ hash[:consumes] = structure.consumes unless structure.consumes.empty?
23
+ hash[:produces] = structure.produces unless structure.produces.empty?
24
+
25
+ hash[:paths] = {}
26
+ structure.paths.each do |key, path|
27
+ hash[:paths][key] = dump_path_to_json(path)
28
+ end
29
+
30
+ hash
31
+ end
32
+
33
+ def to_json
34
+ MultiJson.dump(to_hash)
35
+ end
36
+
37
+ def dump_info_to_json(info)
38
+ hash = {}
39
+ hash[:title] = info.title if info.title?
40
+ hash[:description] = info.description if info.description?
41
+ hash[:version] = info.version if info.version?
42
+ hash[:termsOfService] = info.terms_of_service if info.terms_of_service?
43
+
44
+ if info.license?
45
+ hash[:license] = {}
46
+ hash[:license][:name] = info.license.name if info.license.name?
47
+ hash[:license][:url] = info.license.url if info.license.url?
48
+ end
49
+ hash
50
+ end
51
+
52
+ def dump_path_to_json(path)
53
+ hash = {}
54
+ path.operations.each do |method, operation|
55
+ hash[method] = dump_operation_to_json(operation)
56
+ end
57
+ hash
58
+ end
59
+
60
+ def dump_operation_to_json(operation)
61
+ hash = {}
62
+ hash[:tags] = operation.tags if operation.tags?
63
+ hash[:summary] = operation.summary if operation.summary?
64
+ hash[:description] = operation.description if operation.description?
65
+
66
+ if operation.external_docs?
67
+ hash[:externalDocs] = dump_external_docs_to_json(operation.external_docs)
68
+ end
69
+
70
+ hash[:operationId] = operation.operation_id if operation.operation_id?
71
+ hash[:consumes] = operation.consumes if operation.consumes?
72
+ hash[:produces] = operation.produces if operation.produces?
73
+
74
+ if operation.parameters?
75
+ hash[:parameters] = operation.parameters.map do |parameter|
76
+ dump_parameter_to_json(parameter)
77
+ end
78
+ end
79
+
80
+ hash[:responses] = dump_response_to_json(operation.responses) if operation.responses?
81
+ hash[:schemes] = operation.schemes if operation.schemes?
82
+ hash[:deprecated] = operation.deprecated if operation.deprecated?
83
+
84
+ if operation.security?
85
+ hash[:security] = dump_security_to_json(operation.security)
86
+ end
87
+
88
+ hash
89
+ end
90
+
91
+ def dump_parameter_to_json(parameter)
92
+ hash = {}
93
+
94
+ hash[:name] = parameter.name if parameter.name?
95
+ hash[:in] = parameter.location if parameter.location?
96
+ hash[:description] = parameter.description if parameter.description?
97
+ hash[:required] = parameter.required if parameter.required?
98
+
99
+ if parameter.schema?
100
+ hash[:schema] = dump_schema_to_json(parameter.schema)
101
+ else
102
+ hash[:type] = parameter.type if parameter.type?
103
+ hash[:format] = parameter.format if parameter.format?
104
+ hash[:items] = parameter.items if parameter.items?
105
+ hash[:collectionFormat] = parameter.collection_format if parameter.collection_format?
106
+ hash[:default] = parameter.default if parameter.default?
107
+ hash[:maximum] = parameter.maximum if parameter.maximum?
108
+ hash[:exclusiveMaximum] = parameter.exclusive_maximum if parameter.exclusive_maximum?
109
+ hash[:minimum] = parameter.minimum if parameter.minimum?
110
+ hash[:exclusiveMinimum] = parameter.exclusive_minimum if parameter.exclusive_minimum?
111
+ hash[:maxLength] = parameter.max_length if parameter.max_length?
112
+ hash[:minLength] = parameter.min_length if parameter.min_length?
113
+ hash[:pattern] = parameter.pattern if parameter.pattern?
114
+ hash[:maxItems] = parameter.max_items if parameter.max_items?
115
+ hash[:minItems] = parameter.min_items if parameter.min_items?
116
+ hash[:uniqueItems] = parameter.unique_items if parameter.unique_items?
117
+ hash[:enum] = parameter.enum if parameter.enum?
118
+ hash[:multipleOf] = parameter.multiple_of if parameter.multiple_of?
119
+ end
120
+
121
+ hash
122
+ end
123
+
124
+ def dump_external_docs_to_json(external_docs)
125
+ hash = {}
126
+ hash[:description] = external_docs.description if external_docs.description?
127
+ hash[:url] = external_docs.url if external_docs.url?
128
+ hash
129
+ end
130
+
131
+ def dump_security_to_json(security)
132
+ hash = {}
133
+ hash[:type] = security.type
134
+ hash[:description] = security.description
135
+ hash[:name] = security.name
136
+ hash[:in] = security.location
137
+ hash[:flow] = security.flow
138
+ hash[:authorizationUrl] = security.authorization_url
139
+ hash[:tokenUrl] = security.token_url
140
+ hash[:flow] = security.flow
141
+ hash[:scopes] = security.scopes
142
+ hash
143
+ end
144
+
145
+ def dump_response_to_json(response)
146
+ hash = {}
147
+ hash[:description] = response.description
148
+ hash[:schema] = dump_schema_to_json(response.schema) if response.schema?
149
+ hash[:headers] = dump_headers_to_json(response.headers) if response.headers?
150
+ hash[:examples] = dump_examples_to_json(response.examples) if response.examples?
151
+ hash
152
+ end
153
+
154
+ def dump_schema_to_json(schema)
155
+ hash = {}
156
+ hash[:discriminator] = schema.discriminator if schema.discriminator?
157
+ hash[:readOnly] = schema.read_only?
158
+ hash[:externalDocs] = schema.external_docs if schema.external_docs?
159
+ hash[:description] = schema.description if schema.description?
160
+ hash[:examples] = dump_examples_to_json(schema.examples) if schema.examples?
161
+ hash[:type] = schema.type if schema.type?
162
+ hash[:format] = schema.format if schema.format?
163
+ hash[:items] = schema.items if schema.items?
164
+ hash[:collectionFormat] = schema.collection_format if schema.collection_format?
165
+ hash[:default] = schema.default if schema.default?
166
+ hash[:maximum] = schema.maximum if schema.maximum?
167
+ hash[:exclusiveMaximum] = schema.exclusive_maximum if schema.exclusive_maximum?
168
+ hash[:minimum] = schema.minimum if schema.minimum?
169
+ hash[:exclusiveMinimum] = schema.exclusive_minimum if schema.exclusive_minimum?
170
+ hash[:maxLength] = schema.max_length if schema.max_length?
171
+ hash[:minLength] = schema.min_length if schema.min_length?
172
+ hash[:pattern] = schema.pattern if schema.pattern?
173
+ hash[:maxItems] = schema.max_items if schema.max_items?
174
+ hash[:minItems] = schema.min_items if schema.min_items?
175
+ hash[:uniqueItems] = schema.unique_items if schema.unique_items?
176
+ hash[:enum] = schema.enum if schema.enum?
177
+ hash[:multipleOf] = schema.multiple_of if schema.multiple_of?
178
+ hash
179
+ end
180
+
181
+ def dump_headers_to_json(header)
182
+ hash = {}
183
+
184
+ hash[:description] = header.description if header.description?
185
+ hash[:type] = header.type if header.type?
186
+ hash[:format] = header.format if header.format?
187
+ hash[:items] = header.items if header.items?
188
+ hash[:collectionFormat] = header.collection_format if header.collection_format?
189
+ hash[:default] = header.default if header.default?
190
+ hash[:maximum] = header.maximum if header.maximum?
191
+ hash[:exclusiveMaximum] = header.exclusive_maximum if header.exclusive_maximum?
192
+ hash[:minimum] = header.minimum if header.minimum?
193
+ hash[:exclusiveMinimum] = header.exclusive_minimum if header.exclusive_minimum?
194
+ hash[:maxLength] = header.max_length if header.max_length?
195
+ hash[:minLength] = header.min_length if header.min_length?
196
+ hash[:pattern] = header.pattern if header.pattern?
197
+ hash[:maxItems] = header.max_items if header.max_items?
198
+ hash[:minItems] = header.min_items if header.min_items?
199
+ hash[:uniqueItems] = header.unique_items if header.unique_items?
200
+ hash[:enum] = header.enum if header.enum?
201
+ hash[:multipleOf] = header.multiple_of if header.multiple_of?
202
+
203
+ hash
204
+ end
205
+
206
+ def dump_examples_to_json(schema)
207
+ hash = {}
208
+ hash
209
+ end
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,191 @@
1
+ require 'skeleton/model'
2
+ require 'skeleton/path'
3
+ require 'skeleton/info'
4
+ require 'skeleton/parameter'
5
+ require 'skeleton/responses'
6
+ require 'skeleton/security_definitions'
7
+
8
+ module Skeleton
9
+ class Structure < Model
10
+ attr_accessor :host, :base_path, :external_docs
11
+ attr_presence :info, :host, :base_path, :external_docs, :security
12
+ attr_not_empty :consumes, :responses, :produces, :schemes, :security, :tags,
13
+ :definitions, :parameters, :paths, :security_definitions
14
+
15
+ def responses=(value)
16
+ case value
17
+ when Hash
18
+ Skeleton::Responses.new(value)
19
+ else
20
+ @responses = value
21
+ end
22
+ end
23
+
24
+ def responses
25
+ @responses ||= Skeleton::Responses.new
26
+ end
27
+
28
+ def consumes=(value)
29
+ @consumes = Array(value)
30
+ end
31
+
32
+ def consumes
33
+ @consumes ||= []
34
+ end
35
+
36
+ def produces=(value)
37
+ @produces = Array(value)
38
+ end
39
+
40
+ def produces
41
+ @produces ||= []
42
+ end
43
+
44
+ def schemes=(value)
45
+ @schemes = Array(value)
46
+ end
47
+
48
+ def schemes
49
+ @schemes ||= []
50
+ end
51
+
52
+ def security=(value)
53
+ @security = Array(value)
54
+ end
55
+
56
+ def security
57
+ @security ||= []
58
+ end
59
+
60
+ def tags=(value)
61
+ @tags = Array(value)
62
+ end
63
+
64
+ def tags
65
+ @tags ||= []
66
+ end
67
+
68
+ def info
69
+ @info ||= Skeleton::Info.new
70
+ end
71
+
72
+ def definitions
73
+ @definitions ||= {}
74
+ end
75
+
76
+ def parameters
77
+ @parameters ||= {}
78
+ end
79
+
80
+ def paths
81
+ @paths ||= {}
82
+ end
83
+
84
+ def security_definitions
85
+ @security_definitions ||= Skeleton::SecurityDefinitions.new
86
+ end
87
+
88
+ # Define or get a path. If a block is provided, it will define a new path
89
+ # object. If no block is provided, the current block will be returned
90
+ #
91
+ # @param resource [String] the api path
92
+ #
93
+ # @return [Skeleton::Path]
94
+ def path(resource, &block)
95
+ if block
96
+ path_object = Skeleton::Path.new
97
+ yield(path_object)
98
+ paths[resource] = path_object
99
+ else
100
+ paths[resource]
101
+ end
102
+ end
103
+
104
+ def parameter(location, name, &block)
105
+ param = Skeleton::Parameter.new({name: name})
106
+ yield(param) if block
107
+ parameters[name] = param
108
+ end
109
+
110
+ def to_h
111
+ hash = {}
112
+ hash[:info] = info.to_h if info?
113
+ hash[:host] = host if host?
114
+ hash[:base_path] = base_path if base_path?
115
+ hash[:external_docs] = external_docs if external_docs?
116
+ hash[:schemes] = schemes if schemes?
117
+ hash[:consumes] = consumes if consumes?
118
+ hash[:produces] = produces if produces?
119
+
120
+ if paths?
121
+ hash[:paths] = {}
122
+ paths.each do |resource, path|
123
+ hash[:paths][resource] = path.to_h
124
+ end
125
+ end
126
+
127
+ if parameters?
128
+ hash[:parameters] = {}
129
+ parameters.each do |name, parameter|
130
+ hash[:parameters][name] = parameter.to_h
131
+ end
132
+ end
133
+
134
+ hash[:responses] = responses.to_h if responses?
135
+
136
+ if security_definitions?
137
+ hash[:security_definitions] = security_definitions.to_h
138
+ end
139
+
140
+ if security?
141
+ hash[:security] = security.map(&:to_h)
142
+ end
143
+
144
+ hash[:tags] = tags.map(&:to_h) if tags?
145
+ hash
146
+ end
147
+
148
+ def to_swagger_hash
149
+ hash = {}
150
+ hash[:info] = info.to_swagger_hash if info?
151
+ hash[:host] = host if host?
152
+ hash[:basePath] = base_path if base_path?
153
+ hash[:externalDocs] = external_docs if external_docs?
154
+ hash[:schemes] = schemes if schemes?
155
+ hash[:consumes] = consumes if consumes?
156
+ hash[:produces] = produces if produces?
157
+
158
+ if paths?
159
+ hash[:paths] = {}
160
+ paths.each do |resource, path|
161
+ hash[:paths][resource] = path.to_swagger_hash
162
+ end
163
+ end
164
+
165
+ if parameters?
166
+ hash[:parameters] = {}
167
+ parameters.each do |name, parameter|
168
+ hash[:parameters][name] = parameter.to_swagger_hash
169
+ end
170
+ end
171
+
172
+ if responses?
173
+ hash[:responses] = responses.to_swagger_hash
174
+ end
175
+
176
+ if security_definitions?
177
+ hash[:securityDefinitions] = security_definitions.to_swagger_hash
178
+ end
179
+
180
+ if security?
181
+ hash[:security] = security.map(&:to_swagger_hash)
182
+ end
183
+
184
+ if tags?
185
+ hash[:tags] = tags.map(&:to_swagger_hash)
186
+ end
187
+
188
+ hash
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,24 @@
1
+ require 'skeleton/model'
2
+
3
+ module Skeleton
4
+ class Tag < Model
5
+ attr_accessor :name, :description, :external_docs
6
+ attr_presence :name, :description, :external_docs
7
+
8
+ def to_h
9
+ hash = {}
10
+ hash[:name] = name if name?
11
+ hash[:description] = description if description?
12
+ hash[:external_docs] = external_docs if external_docs?
13
+ hash
14
+ end
15
+
16
+ def to_swagger_hash
17
+ hash = {}
18
+ hash[:name] = name if name?
19
+ hash[:description] = description if description?
20
+ hash[:externalDocs] = external_docs if external_docs?
21
+ hash
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module Skeleton
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -0,0 +1,130 @@
1
+ require 'spec_helper'
2
+
3
+ require 'skeleton'
4
+ require 'skeleton/serializers/swagger'
5
+ require 'pp'
6
+
7
+ describe 'A simple use case' do
8
+ describe 'validating the first case' do
9
+ it 'works' do
10
+ @structure = Skeleton.build do |s|
11
+ s.host = 'api.example.com'
12
+ s.info.version = '1.0'
13
+ s.info.title = 'Waffles Emporium API'
14
+ s.info.description = 'A test integration'
15
+
16
+ s.info.contact.name = 'WarmWaffles'
17
+ s.info.contact.email = 'warmwaffles@gmail.com'
18
+ s.info.contact.url = 'https://github.com/warmwaffles/skeleton'
19
+
20
+ s.info.license.name = 'MIT'
21
+
22
+ s.schemes = %w(https)
23
+ s.consumes = %(application/json)
24
+ s.produces = %(application/json)
25
+
26
+ s.path('/users') do |path|
27
+ path.get do |o|
28
+ o.tag('users')
29
+ o.parameter(:query, 'limit') do |p|
30
+ p.description = 'maximum number of results to return'
31
+ p.type = 'integer'
32
+ p.format = 'int32'
33
+ p.required = false
34
+ end
35
+ o.parameter(:query, 'offset') do |p|
36
+ p.description = 'offset within the results returned'
37
+ p.type = 'integer'
38
+ p.format = 'int32'
39
+ p.required = false
40
+ end
41
+ end
42
+
43
+ path.post do |o|
44
+ o.tag('user')
45
+ o.parameter(:body, 'user[email]') do |p|
46
+ p.description = 'the user email'
47
+ p.type = 'string'
48
+ p.required = true
49
+ end
50
+ o.parameter(:body, 'user[name]') do |p|
51
+ p.description = 'the user name'
52
+ p.type = 'string'
53
+ p.required = true
54
+ end
55
+ o.parameter(:body, 'user[password]') do |p|
56
+ p.description = 'the user password'
57
+ p.type = 'string'
58
+ p.required = true
59
+ end
60
+ o.parameter(:body, 'user[password_confirmation]') do |p|
61
+ p.description = 'the user password confirmation'
62
+ p.type = 'string'
63
+ p.required = true
64
+ end
65
+ end
66
+ end
67
+
68
+ s.path('/users/{user_id}') do |path|
69
+ path.get do |o|
70
+ o.tag('user')
71
+ o.parameter(:query, 'user_id') do |p|
72
+ p.description = 'the user id'
73
+ p.type = 'string'
74
+ p.format = 'uuid'
75
+ p.required = true
76
+ end
77
+ end
78
+
79
+ path.put do |o|
80
+ o.tag('user')
81
+ o.parameter(:body, 'user[email]') do |p|
82
+ p.description = 'the user email'
83
+ p.type = 'string'
84
+ p.required = false
85
+ end
86
+ o.parameter(:body, 'user[name]') do |p|
87
+ p.description = 'the user name'
88
+ p.type = 'string'
89
+ p.required = false
90
+ end
91
+ o.parameter(:body, 'user[password]') do |p|
92
+ p.description = 'the user password'
93
+ p.type = 'string'
94
+ p.required = false
95
+ end
96
+ o.parameter(:body, 'user[password_confirmation]') do |p|
97
+ p.description = 'the user password confirmation'
98
+ p.type = 'string'
99
+ p.required = false
100
+ end
101
+ end
102
+
103
+ path.patch do |o|
104
+ o.tag('user')
105
+ o.parameter(:body, 'user[email]') do |p|
106
+ p.description = 'the user email'
107
+ p.type = 'string'
108
+ p.required = false
109
+ end
110
+ o.parameter(:body, 'user[name]') do |p|
111
+ p.description = 'the user name'
112
+ p.type = 'string'
113
+ p.required = false
114
+ end
115
+ o.parameter(:body, 'user[password]') do |p|
116
+ p.description = 'the user password'
117
+ p.type = 'string'
118
+ p.required = false
119
+ end
120
+ o.parameter(:body, 'user[password_confirmation]') do |p|
121
+ p.description = 'the user password confirmation'
122
+ p.type = 'string'
123
+ p.required = false
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end