skeleton 0.2.0 → 0.3.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 (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