skeleton 0.3.3 → 0.4.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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.md +140 -65
  4. data/Rakefile +10 -3
  5. data/lib/skeleton.rb +6 -10
  6. data/lib/skeleton/contact.rb +1 -13
  7. data/lib/skeleton/error.rb +4 -0
  8. data/lib/skeleton/graph.rb +56 -0
  9. data/lib/skeleton/header.rb +2 -63
  10. data/lib/skeleton/items.rb +34 -0
  11. data/lib/skeleton/license.rb +1 -12
  12. data/lib/skeleton/model.rb +13 -17
  13. data/lib/skeleton/operation.rb +50 -121
  14. data/lib/skeleton/parameter.rb +31 -88
  15. data/lib/skeleton/parameters.rb +40 -0
  16. data/lib/skeleton/path.rb +42 -80
  17. data/lib/skeleton/presenter.rb +19 -0
  18. data/lib/skeleton/property.rb +6 -0
  19. data/lib/skeleton/response.rb +24 -45
  20. data/lib/skeleton/schema.rb +80 -63
  21. data/lib/skeleton/scope.rb +18 -0
  22. data/lib/skeleton/security_scheme.rb +19 -37
  23. data/lib/skeleton/serializers/options.rb +215 -0
  24. data/lib/skeleton/serializers/swagger.rb +197 -0
  25. data/lib/skeleton/structure.rb +92 -138
  26. data/lib/skeleton/swagger.rb +9 -0
  27. data/lib/skeleton/tag.rb +11 -16
  28. data/lib/skeleton/version.rb +1 -1
  29. data/skeleton.gemspec +2 -0
  30. data/test/fixtures/json-schema-draft-04.json +150 -0
  31. data/test/fixtures/schema.json +1482 -0
  32. data/test/integrations/validate_complex_schema_spec.rb +42 -0
  33. data/test/skeleton/graph_test.rb +22 -0
  34. data/test/skeleton/mapper_test.rb +84 -0
  35. data/test/skeleton/operation_test.rb +11 -0
  36. data/test/skeleton/parameter_test.rb +34 -0
  37. data/test/skeleton/parameters_test.rb +9 -0
  38. data/test/skeleton/path_test.rb +46 -0
  39. data/test/skeleton/property_test.rb +8 -0
  40. data/test/skeleton/serializers/options_test.rb +68 -0
  41. data/test/skeleton/serializers/swagger_test.rb +30 -0
  42. data/test/support/factories/structure_factory.rb +86 -0
  43. data/test/support/fixtures.rb +6 -0
  44. data/test/support/kissmetrics/core_api.rb +542 -0
  45. data/{spec/spec_helper.rb → test/test_helper.rb} +7 -1
  46. metadata +73 -25
  47. data/lib/skeleton/config.rb +0 -37
  48. data/lib/skeleton/documentation.rb +0 -17
  49. data/lib/skeleton/example.rb +0 -31
  50. data/lib/skeleton/headers.rb +0 -50
  51. data/lib/skeleton/helpers/controller_helpers.rb +0 -25
  52. data/lib/skeleton/info.rb +0 -40
  53. data/lib/skeleton/item.rb +0 -99
  54. data/lib/skeleton/responses.rb +0 -59
  55. data/lib/skeleton/scopes.rb +0 -24
  56. data/lib/skeleton/security_definitions.rb +0 -46
  57. data/lib/skeleton/security_requirement.rb +0 -29
  58. data/spec/integrations/use_case_spec.rb +0 -131
  59. data/spec/skeleton/operation_spec.rb +0 -113
  60. data/spec/skeleton/serializers/contact_spec.rb +0 -30
  61. data/spec/skeleton/serializers/documentation_spec.rb +0 -23
  62. data/spec/skeleton/serializers/header_spec.rb +0 -57
@@ -1,192 +1,146 @@
1
- require 'skeleton/model'
1
+ require 'set'
2
+
2
3
  require 'skeleton/path'
3
- require 'skeleton/info'
4
+ require 'skeleton/model'
5
+ require 'skeleton/contact'
6
+ require 'skeleton/license'
7
+ require 'skeleton/tag'
8
+ require 'skeleton/scope'
4
9
  require 'skeleton/parameter'
5
- require 'skeleton/responses'
6
- require 'skeleton/security_definitions'
10
+ require 'skeleton/response'
11
+ require 'skeleton/security_scheme'
7
12
 
8
13
  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)
14
+ class Structure
15
+ attr_accessor :terms, :host, :base_path, :title, :version, :description,
16
+ :external_docs
17
+
18
+ alias_method :describe, :description=
19
+
20
+ def configure(&block)
21
+ return self unless block
22
+
23
+ if block.arity == 0
24
+ self.instance_eval(&block)
19
25
  else
20
- @responses = value
26
+ yield(self)
21
27
  end
22
- end
23
28
 
24
- def responses
25
- @responses ||= Skeleton::Responses.new
29
+ self
26
30
  end
27
31
 
28
- def consumes=(value)
29
- @consumes = Array(value)
32
+ def schemes
33
+ @schemes ||= Set.new
30
34
  end
31
35
 
32
36
  def consumes
33
- @consumes ||= []
34
- end
35
-
36
- def produces=(value)
37
- @produces = Array(value)
37
+ @consumes ||= Set.new
38
38
  end
39
39
 
40
40
  def produces
41
- @produces ||= []
41
+ @produces ||= Set.new
42
42
  end
43
43
 
44
- def schemes=(value)
45
- @schemes = Array(value)
44
+ def license
45
+ @license ||= Skeleton::License.new
46
46
  end
47
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 ||= []
48
+ def tags
49
+ @tags ||= {}
58
50
  end
59
51
 
60
- def tags=(value)
61
- @tags = Array(value)
52
+ def contact
53
+ @contact ||= Skeleton::Contact.new
62
54
  end
63
55
 
64
- def tags
65
- @tags ||= []
56
+ def responses
57
+ @responses ||= {}
66
58
  end
67
59
 
68
- def info
69
- @info ||= Skeleton::Info.new
60
+ def parameters
61
+ @parameters ||= {}
70
62
  end
71
63
 
72
- def definitions
73
- @definitions ||= {}
64
+ def scopes
65
+ @scopes ||= {}
74
66
  end
75
67
 
76
- def parameters
77
- @parameters ||= {}
68
+ def security
69
+ @security ||= {}
78
70
  end
79
71
 
80
72
  def paths
81
73
  @paths ||= {}
82
74
  end
83
75
 
84
- def security_definitions
85
- @security_definitions ||= Skeleton::SecurityDefinitions.new
76
+ def models
77
+ @models ||= {}
86
78
  end
87
79
 
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
80
+ def scheme(*types)
81
+ types.flatten.each { |t| schemes.add(t.to_s) }
102
82
  end
103
83
 
104
- def parameter(location, name, &block)
105
- param = Skeleton::Parameter.new({name: name})
106
- yield(param) if block
107
- parameters[name] = param
84
+ def consume(*types)
85
+ types.flatten.each { |t| consumes.add(t.to_s) }
108
86
  end
109
87
 
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
88
+ def produce(*types)
89
+ types.flatten.each { |t| produces.add(t.to_s) }
90
+ end
133
91
 
134
- hash[:responses] = responses.to_h if responses?
92
+ def parameters?
93
+ !parameters.empty?
94
+ end
135
95
 
136
- if security_definitions?
137
- hash[:security_definitions] = security_definitions.to_h
138
- end
96
+ def responses?
97
+ !responses.empty?
98
+ end
139
99
 
140
- if security?
141
- hash[:security] = security.map(&:to_h)
142
- end
100
+ def secure?
101
+ !security.empty?
102
+ end
143
103
 
144
- hash[:tags] = tags.map(&:to_h) if tags?
145
- hash
146
- end
147
-
148
- def to_swagger_hash
149
- hash = {}
150
- hash[:swagger] = '2.0'
151
- hash[:info] = info.to_swagger_hash if info?
152
- hash[:host] = host if host?
153
- hash[:basePath] = base_path if base_path?
154
- hash[:externalDocs] = external_docs if external_docs?
155
- hash[:schemes] = schemes if schemes?
156
- hash[:consumes] = consumes if consumes?
157
- hash[:produces] = produces if produces?
158
-
159
- if paths?
160
- hash[:paths] = {}
161
- paths.each do |resource, path|
162
- hash[:paths][resource] = path.to_swagger_hash
163
- end
164
- end
104
+ def define_response(name, &block)
105
+ responses[name] = Skeleton::Response.new
106
+ responses[name].instance_eval(&block) if block
107
+ responses[name]
108
+ end
165
109
 
166
- if parameters?
167
- hash[:parameters] = {}
168
- parameters.each do |name, parameter|
169
- hash[:parameters][name] = parameter.to_swagger_hash
170
- end
171
- end
110
+ def define_parameter(name, &block)
111
+ parameters[name] = Skeleton::Parameter.new
112
+ parameters[name].instance_eval(&block) if block
113
+ parameters[name]
114
+ end
172
115
 
173
- if responses?
174
- hash[:responses] = responses.to_swagger_hash
175
- end
116
+ def define_scope(name, &block)
117
+ scopes[name] = Skeleton::Scope.new
118
+ scopes[name].instance_eval(&block) if block
119
+ scopes[name]
120
+ end
176
121
 
177
- if security_definitions?
178
- hash[:securityDefinitions] = security_definitions.to_swagger_hash
179
- end
122
+ def define_security(name, &block)
123
+ security[name] = Skeleton::SecurityScheme.new(name: name)
124
+ security[name].instance_eval(&block) if block
125
+ security[name]
126
+ end
180
127
 
181
- if security?
182
- hash[:security] = security.map(&:to_swagger_hash)
183
- end
128
+ def define_tag(name, &block)
129
+ tags[name] = Skeleton::Tag.new(name: name)
130
+ tags[name].instance_eval(&block) if block
131
+ tags[name]
132
+ end
184
133
 
185
- if tags?
186
- hash[:tags] = tags.map(&:to_swagger_hash)
187
- end
134
+ def define_path(path, options={}, &block)
135
+ paths[path] = Skeleton::Path.new
136
+ paths[path].instance_eval(&block) if block
137
+ paths[path]
138
+ end
188
139
 
189
- hash
140
+ def define_model(name, options={}, &block)
141
+ models[name] = Skeleton::Model.new(name: name)
142
+ models[name].instance_eval(&block) if block
143
+ models[name]
190
144
  end
191
145
  end
192
146
  end
@@ -0,0 +1,9 @@
1
+ require 'skeleton/swagger/serializer'
2
+
3
+ module Skeleton
4
+ module Swagger
5
+ def self.serialize(structure)
6
+ Skeleton::Swagger::Serializer.new(structure).to_h
7
+ end
8
+ end
9
+ end
@@ -1,24 +1,19 @@
1
- require 'skeleton/model'
2
-
1
+ require 'skeleton/attributes'
3
2
  module Skeleton
4
- class Tag < Model
3
+ class Tag
4
+ extend Skeleton::Attributes
5
+
5
6
  attr_accessor :name, :description, :external_docs
6
7
  attr_presence :name, :description, :external_docs
7
8
 
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
9
+ def initialize(args={})
10
+ args.each do |k, v|
11
+ setter = "#{k}="
12
+ self.send(setter, v) if self.respond_to?(setter)
13
+ end
14
14
  end
15
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
16
+ alias_method :describe, :description=
17
+ alias_method :document, :external_docs=
23
18
  end
24
19
  end
@@ -1,3 +1,3 @@
1
1
  module Skeleton
2
- VERSION = '0.3.3'
2
+ VERSION = '0.4.1'
3
3
  end
@@ -23,4 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency('bundler', '~> 1.6')
24
24
  spec.add_development_dependency('rake')
25
25
  spec.add_development_dependency('minitest')
26
+ spec.add_development_dependency('json-schema')
27
+ spec.add_development_dependency('webmock')
26
28
  end
@@ -0,0 +1,150 @@
1
+ {
2
+ "id": "http://json-schema.org/draft-04/schema#",
3
+ "$schema": "http://json-schema.org/draft-04/schema#",
4
+ "description": "Core schema meta-schema",
5
+ "definitions": {
6
+ "schemaArray": {
7
+ "type": "array",
8
+ "minItems": 1,
9
+ "items": { "$ref": "#" }
10
+ },
11
+ "positiveInteger": {
12
+ "type": "integer",
13
+ "minimum": 0
14
+ },
15
+ "positiveIntegerDefault0": {
16
+ "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
17
+ },
18
+ "simpleTypes": {
19
+ "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
20
+ },
21
+ "stringArray": {
22
+ "type": "array",
23
+ "items": { "type": "string" },
24
+ "minItems": 1,
25
+ "uniqueItems": true
26
+ }
27
+ },
28
+ "type": "object",
29
+ "properties": {
30
+ "id": {
31
+ "type": "string",
32
+ "format": "uri"
33
+ },
34
+ "$schema": {
35
+ "type": "string",
36
+ "format": "uri"
37
+ },
38
+ "title": {
39
+ "type": "string"
40
+ },
41
+ "description": {
42
+ "type": "string"
43
+ },
44
+ "default": {},
45
+ "multipleOf": {
46
+ "type": "number",
47
+ "minimum": 0,
48
+ "exclusiveMinimum": true
49
+ },
50
+ "maximum": {
51
+ "type": "number"
52
+ },
53
+ "exclusiveMaximum": {
54
+ "type": "boolean",
55
+ "default": false
56
+ },
57
+ "minimum": {
58
+ "type": "number"
59
+ },
60
+ "exclusiveMinimum": {
61
+ "type": "boolean",
62
+ "default": false
63
+ },
64
+ "maxLength": { "$ref": "#/definitions/positiveInteger" },
65
+ "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
66
+ "pattern": {
67
+ "type": "string",
68
+ "format": "regex"
69
+ },
70
+ "additionalItems": {
71
+ "anyOf": [
72
+ { "type": "boolean" },
73
+ { "$ref": "#" }
74
+ ],
75
+ "default": {}
76
+ },
77
+ "items": {
78
+ "anyOf": [
79
+ { "$ref": "#" },
80
+ { "$ref": "#/definitions/schemaArray" }
81
+ ],
82
+ "default": {}
83
+ },
84
+ "maxItems": { "$ref": "#/definitions/positiveInteger" },
85
+ "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
86
+ "uniqueItems": {
87
+ "type": "boolean",
88
+ "default": false
89
+ },
90
+ "maxProperties": { "$ref": "#/definitions/positiveInteger" },
91
+ "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
92
+ "required": { "$ref": "#/definitions/stringArray" },
93
+ "additionalProperties": {
94
+ "anyOf": [
95
+ { "type": "boolean" },
96
+ { "$ref": "#" }
97
+ ],
98
+ "default": {}
99
+ },
100
+ "definitions": {
101
+ "type": "object",
102
+ "additionalProperties": { "$ref": "#" },
103
+ "default": {}
104
+ },
105
+ "properties": {
106
+ "type": "object",
107
+ "additionalProperties": { "$ref": "#" },
108
+ "default": {}
109
+ },
110
+ "patternProperties": {
111
+ "type": "object",
112
+ "additionalProperties": { "$ref": "#" },
113
+ "default": {}
114
+ },
115
+ "dependencies": {
116
+ "type": "object",
117
+ "additionalProperties": {
118
+ "anyOf": [
119
+ { "$ref": "#" },
120
+ { "$ref": "#/definitions/stringArray" }
121
+ ]
122
+ }
123
+ },
124
+ "enum": {
125
+ "type": "array",
126
+ "minItems": 1,
127
+ "uniqueItems": true
128
+ },
129
+ "type": {
130
+ "anyOf": [
131
+ { "$ref": "#/definitions/simpleTypes" },
132
+ {
133
+ "type": "array",
134
+ "items": { "$ref": "#/definitions/simpleTypes" },
135
+ "minItems": 1,
136
+ "uniqueItems": true
137
+ }
138
+ ]
139
+ },
140
+ "allOf": { "$ref": "#/definitions/schemaArray" },
141
+ "anyOf": { "$ref": "#/definitions/schemaArray" },
142
+ "oneOf": { "$ref": "#/definitions/schemaArray" },
143
+ "not": { "$ref": "#" }
144
+ },
145
+ "dependencies": {
146
+ "exclusiveMaximum": [ "maximum" ],
147
+ "exclusiveMinimum": [ "minimum" ]
148
+ },
149
+ "default": {}
150
+ }