api_sketch 0.1.1 → 0.1.2

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGELOG.md +7 -2
  4. data/README.md +63 -9
  5. data/api_sketch.gemspec +0 -1
  6. data/examples/api_project/config/initializers/shared_blocks.rb +15 -0
  7. data/examples/api_project/resources/places.rb +138 -0
  8. data/examples/api_project/resources/users/points/stats.rb +30 -0
  9. data/examples/api_project/resources/users/points.rb +32 -0
  10. data/examples/api_project/resources/users.rb +341 -0
  11. data/lib/api_sketch/config.rb +1 -1
  12. data/lib/api_sketch/dsl/attribute_parser.rb +19 -0
  13. data/lib/api_sketch/dsl/attributes.rb +45 -0
  14. data/lib/api_sketch/dsl/base.rb +8 -0
  15. data/lib/api_sketch/dsl/complex_attribute_parser.rb +11 -0
  16. data/lib/api_sketch/dsl/headers.rb +17 -0
  17. data/lib/api_sketch/dsl/parameters.rb +31 -0
  18. data/lib/api_sketch/dsl/responses.rb +22 -0
  19. data/lib/api_sketch/dsl.rb +27 -165
  20. data/lib/api_sketch/examples_server.rb +1 -1
  21. data/lib/api_sketch/generators/base.rb +42 -0
  22. data/lib/api_sketch/{generators.rb → generators/bootstrap.rb} +2 -46
  23. data/lib/api_sketch/model/attribute.rb +42 -0
  24. data/lib/api_sketch/model/base.rb +17 -0
  25. data/lib/api_sketch/model/header.rb +7 -0
  26. data/lib/api_sketch/model/parameters.rb +50 -0
  27. data/lib/api_sketch/model/resource.rb +99 -0
  28. data/lib/api_sketch/model/response.rb +12 -0
  29. data/lib/api_sketch/model/shared_block.rb +17 -0
  30. data/lib/api_sketch/model.rb +0 -242
  31. data/lib/api_sketch/{renderers.rb → response_renderer.rb} +0 -0
  32. data/lib/api_sketch/version.rb +1 -1
  33. data/lib/api_sketch.rb +20 -3
  34. data/spec/lib/api_sketch/dsl/attribute_parser_spec.rb +14 -0
  35. data/spec/lib/api_sketch/dsl/attributes_spec.rb +14 -0
  36. data/spec/lib/api_sketch/dsl/complex_attribute_parser_spec.rb +14 -0
  37. data/spec/lib/api_sketch/dsl/headers_spec.rb +14 -0
  38. data/spec/lib/api_sketch/dsl/parameters_spec.rb +14 -0
  39. data/spec/lib/api_sketch/dsl/responses_spec.rb +14 -0
  40. data/spec/lib/api_sketch/dsl_spec.rb +5 -3
  41. data/spec/lib/api_sketch/model/parameters_spec.rb +28 -0
  42. data/spec/lib/api_sketch/{renderers_spec.rb → response_renderer_spec.rb} +51 -1
  43. data/spec/spec_helper.rb +3 -1
  44. data/spec/support/shared_examples.rb +9 -0
  45. metadata +43 -9
  46. data/.ruby-gemset +0 -1
  47. data/.ruby-version +0 -1
@@ -1,244 +1,2 @@
1
1
  module ApiSketch::Model
2
-
3
- class Base
4
-
5
- attr_accessor :name, :description
6
-
7
- def initialize(attributes = {})
8
- attributes = default_values_hash.merge(attributes)
9
- attributes.each do |attribute, value|
10
- self.send("#{attribute}=", value)
11
- end
12
- end
13
-
14
- private
15
- def default_values_hash
16
- {}
17
- end
18
-
19
- end
20
-
21
-
22
- class Attribute < ApiSketch::Model::Base
23
- attr_accessor :data_type, :value, :example, :required, :default, :content
24
-
25
- def example_value(defaults_allowed=false)
26
- value = self.example
27
- value ||= example_value_default if defaults_allowed
28
-
29
- value.respond_to?(:call) ? value.call : value
30
- end
31
-
32
- # TODO: These default values should be configurable via DSL
33
- # Some logic to defer value example from key name, - email from key with email part inside, etc.
34
- def example_value_default
35
- {
36
- integer: lambda { rand(1000) + 1 },
37
- string: lambda { "random_string_#{('A'..'Z').to_a.shuffle.first(8).join}" },
38
- float: lambda { rand(100) + rand(100) * 0.01 },
39
- boolean: lambda { [true, false].sample },
40
- datetime: lambda { Time.now.strftime("%d-%m-%Y %H:%M:%S") },
41
- timestamp: lambda { Time.now.to_i }
42
- }[data_type]
43
- end
44
-
45
- def to_hash
46
- {
47
- data_type: self.data_type,
48
- example_value: self.example_value,
49
- required: !!self.required,
50
- default: self.default,
51
- content: self.content_to_hash
52
- }
53
- end
54
-
55
- def content_to_hash
56
- if self.content
57
- self.content.map do |item|
58
- item.to_hash
59
- end
60
- end
61
- end
62
-
63
- end
64
-
65
-
66
- class Header < ApiSketch::Model::Base
67
- attr_accessor :value, :example, :required
68
-
69
- def example_value
70
- self.example.respond_to?(:call) ? self.example.call : self.example
71
- end
72
- end
73
-
74
-
75
- class Parameters < ApiSketch::Model::Base
76
- attr_accessor :query, :body, :query_container_type, :body_container_type
77
-
78
- def initialize(attributes = {})
79
- super(attributes)
80
- self.query ||= []
81
- self.body ||= []
82
- end
83
-
84
- def as_full_names
85
- fullname_params = self.class.new
86
- [:query, :body].each do |param_location|
87
- new_params = []
88
- self.send(param_location).each do |param|
89
- if param.data_type == :document
90
- full_names_for(param, param.name, new_params)
91
- else
92
- new_params << param
93
- end
94
- end
95
- fullname_params.send("#{param_location}=", new_params)
96
- end
97
- fullname_params
98
- end
99
-
100
- private
101
- def full_names_for(param, name = "", new_params)
102
- name = name.to_s # ensure that this value is always a string
103
- if param.content.kind_of?(Array)
104
- param.content.each do |attribute|
105
- renamed_attribute = attribute.clone
106
- renamed_attribute.name = name.empty? ? attribute.name.to_s : "#{name}[#{attribute.name}]"
107
- if renamed_attribute.data_type == :document
108
- full_names_for(renamed_attribute, renamed_attribute.name, new_params)
109
- else
110
- new_params << renamed_attribute
111
- end
112
- end
113
- end
114
- end
115
- end
116
-
117
-
118
- class Resource < ApiSketch::Model::Base
119
-
120
- attr_accessor :namespace, :action, :path, :http_method, :format, :headers, :parameters, :responses
121
-
122
- # TODO: update this method to provide better id that is used as part of filename
123
- def id
124
- [self.namespace, self.action].reject { |v| v.nil? || v == "" }.join("/")
125
- end
126
-
127
- class << self
128
-
129
- def create(attributes)
130
- res = self.new(attributes)
131
- res.send(:run_validations!)
132
- self.add(res)
133
- res
134
- end
135
-
136
- def add(resource)
137
- @resources ||= []
138
- @resources << resource
139
- end
140
-
141
- def reset!
142
- @resources = []
143
- end
144
-
145
- def reload!(definitions_dir)
146
- self.reset!
147
- ApiSketch::DSL.new(definitions_dir).init!
148
- end
149
-
150
- def all
151
- @resources ||= []
152
- end
153
-
154
- def find(id)
155
- self.all.find { |res| res.id == id }
156
- end
157
-
158
- def find_by_http_method_and_path(http_method, path)
159
- self.all.find { |res| res.http_method == http_method && res.path == path }
160
- end
161
-
162
- def first
163
- self.all.first
164
- end
165
-
166
- def last
167
- self.all.last
168
- end
169
-
170
- def count
171
- self.all.count
172
- end
173
-
174
- end
175
-
176
- private
177
- def default_values_hash
178
- {
179
- http_method: "GET",
180
- format: "json",
181
- headers: [],
182
- parameters: ::ApiSketch::Model::Parameters.new,
183
- responses: []
184
- }
185
- end
186
-
187
- def error_message(message)
188
- # puts_error(message)
189
- raise ::ApiSketch::Error, message
190
- end
191
-
192
- def run_validations!
193
- unless self.action =~ /\A\w*\z/
194
- error_message("'#{self.action}' is invalid action value")
195
- end
196
-
197
- if self.class.find(self.id)
198
- error_message("'#{self.id}' is not unique id. Change values of 'namespace' and/or 'action' attributes")
199
- end
200
-
201
- if self.http_method.nil? || self.http_method.empty?
202
- error_message("request http_method can't be blank")
203
- end
204
-
205
- if self.path.nil? || self.path.empty?
206
- error_message("request path can't be blank")
207
- end
208
-
209
- if self.class.find_by_http_method_and_path(self.http_method, self.path)
210
- error_message("Route '#{self.http_method} #{self.path}' should be unique")
211
- end
212
- end
213
-
214
- end
215
-
216
-
217
- class Response < ApiSketch::Model::Base
218
- attr_accessor :http_status, :parameters, :format, :headers
219
-
220
- private
221
- def default_values_hash
222
- {
223
- format: "json",
224
- headers: [],
225
- parameters: ::ApiSketch::Model::Parameters.new
226
- }
227
- end
228
- end
229
-
230
- module SharedBlock
231
- @list_hash = {}
232
-
233
- class << self
234
- def add(name, block)
235
- @list_hash[name] = block
236
- end
237
-
238
- def find(name)
239
- @list_hash[name] || raise(::ApiSketch::Error, "Shared block '#{name}' is not defined")
240
- end
241
- end
242
- end
243
-
244
2
  end
@@ -1,3 +1,3 @@
1
1
  module ApiSketch
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/lib/api_sketch.rb CHANGED
@@ -8,12 +8,29 @@ require 'fileutils'
8
8
 
9
9
  module ApiSketch
10
10
  require "api_sketch/dsl"
11
+ require "api_sketch/dsl/base"
12
+ require "api_sketch/dsl/attribute_parser"
13
+ require "api_sketch/dsl/attributes"
14
+ require "api_sketch/dsl/complex_attribute_parser"
15
+ require "api_sketch/dsl/headers"
16
+ require "api_sketch/dsl/parameters"
17
+ require "api_sketch/dsl/responses"
18
+
11
19
  require "api_sketch/model"
20
+ require "api_sketch/model/base"
21
+ require "api_sketch/model/attribute"
22
+ require "api_sketch/model/header"
23
+ require "api_sketch/model/parameters"
24
+ require "api_sketch/model/resource"
25
+ require "api_sketch/model/response"
26
+ require "api_sketch/model/shared_block"
27
+
12
28
  require "api_sketch/error"
13
- require "api_sketch/generators"
29
+ require "api_sketch/generators/base"
30
+ require "api_sketch/generators/bootstrap"
14
31
  require "api_sketch/helpers"
15
32
  require "api_sketch/config"
16
- require "api_sketch/renderers"
33
+ require "api_sketch/response_renderer"
17
34
  require "api_sketch/examples_server"
18
35
  require "api_sketch/runner"
19
- end
36
+ end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiSketch::DSL::AttributeParser do
4
+
5
+ let(:simple_instance) {
6
+ described_class.new(:document, &(Proc.new {}) )
7
+ }
8
+
9
+ context "instance methods" do
10
+ subject { simple_instance }
11
+ it_should_behave_like "supports shared blocks"
12
+ end
13
+
14
+ end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiSketch::DSL::Attributes do
4
+
5
+ let(:simple_instance) {
6
+ described_class.new(:document, &(Proc.new {}) )
7
+ }
8
+
9
+ context "instance methods" do
10
+ subject { simple_instance }
11
+ it_should_behave_like "supports shared blocks"
12
+ end
13
+
14
+ end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiSketch::DSL::ComplexAttributeParser do
4
+
5
+ let(:simple_instance) {
6
+ described_class.new(:document, &(Proc.new {}) )
7
+ }
8
+
9
+ context "instance methods" do
10
+ subject { simple_instance }
11
+ it_should_behave_like "supports shared blocks"
12
+ end
13
+
14
+ end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiSketch::DSL::Headers do
4
+
5
+ let(:simple_instance) {
6
+ described_class.new( &(Proc.new {}) )
7
+ }
8
+
9
+ context "instance methods" do
10
+ subject { simple_instance }
11
+ it_should_behave_like "supports shared blocks"
12
+ end
13
+
14
+ end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiSketch::DSL::Parameters do
4
+
5
+ let(:simple_instance) {
6
+ described_class.new( &(Proc.new {}) )
7
+ }
8
+
9
+ context "instance methods" do
10
+ subject { simple_instance }
11
+ it_should_behave_like "supports shared blocks"
12
+ end
13
+
14
+ end
@@ -0,0 +1,14 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiSketch::DSL::Responses do
4
+
5
+ let(:simple_instance) {
6
+ described_class.new( &(Proc.new {}) )
7
+ }
8
+
9
+ context "instance methods" do
10
+ subject { simple_instance }
11
+ it_should_behave_like "supports shared blocks"
12
+ end
13
+
14
+ end
@@ -1,6 +1,7 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe ApiSketch::DSL do
4
+
4
5
  context "document" do
5
6
  context "when all data has key names" do
6
7
  before do
@@ -483,7 +484,7 @@ describe ApiSketch::DSL do
483
484
  @definition_block = definition
484
485
 
485
486
  @shared_block = Proc.new do
486
- shared_block("short user data", definition)
487
+ shared_block("short user data", &definition)
487
488
  end
488
489
  end
489
490
 
@@ -501,7 +502,7 @@ describe ApiSketch::DSL do
501
502
  string "test_key" do
502
503
  end
503
504
 
504
- shared "short user data"
505
+ use_shared_block "short user data"
505
506
  end
506
507
  end
507
508
  end
@@ -530,7 +531,7 @@ describe ApiSketch::DSL do
530
531
  string "test_key" do
531
532
  end
532
533
 
533
- shared "non existing shared data"
534
+ use_shared_block "non existing shared data"
534
535
  end
535
536
  end
536
537
  end
@@ -543,4 +544,5 @@ describe ApiSketch::DSL do
543
544
 
544
545
  end
545
546
  end
547
+
546
548
  end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ describe ApiSketch::Model::Parameters do
4
+
5
+ context "instance methods" do
6
+ let(:instance) {
7
+ element_1 = ApiSketch::Model::Attribute.new(data_type: "string", value: "Test")
8
+ ApiSketch::Model::Parameters.new({query: [], body: [element_1], body_container_type: "array", query_container_type: "document"})
9
+ }
10
+
11
+ describe "#wrapped_body" do
12
+ it "should return ApiSketch::Model::Attribute object" do
13
+ attribute = instance.wrapped_body
14
+ expect(attribute.content).to eql instance.body
15
+ expect(attribute.data_type).to eql "array"
16
+ end
17
+ end
18
+
19
+ describe "#wrapped_query" do
20
+ it "should return ApiSketch::Model::Attribute object" do
21
+ attribute = instance.wrapped_query
22
+ expect(attribute.content).to eql instance.query
23
+ expect(attribute.data_type).to eql "document"
24
+ end
25
+ end
26
+ end
27
+
28
+ end
@@ -33,6 +33,41 @@ describe ApiSketch::ResponseRenderer do
33
33
  end
34
34
  }
35
35
 
36
+
37
+ let(:array_response) {
38
+ Proc.new do
39
+ resource "Array of documents" do
40
+ action "index"
41
+ namespace "simple_data"
42
+ path "/api/test_datas.json"
43
+ http_method "GET"
44
+ format "json"
45
+
46
+ responses do
47
+ context "Success" do
48
+ http_status :ok
49
+
50
+ parameters do
51
+ body :array do
52
+ document do
53
+ description "some data"
54
+ content do
55
+ string "name" do
56
+ example { "Test User #{rand(100)}" }
57
+ end
58
+ integer "id" do
59
+ example { rand(100) + 1 }
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ }
70
+
36
71
  let(:resource_example_definition) {
37
72
  Proc.new do
38
73
  resource "Get test data" do
@@ -120,6 +155,21 @@ describe ApiSketch::ResponseRenderer do
120
155
 
121
156
  expect(result).to eql expected_hash
122
157
  end
158
+
159
+ context "array root response" do
160
+ it "should return proper elements amount at response array" do
161
+ ApiSketch::DSL.new.instance_eval(&array_response)
162
+ response = ApiSketch::Model::Resource.find("simple_data/index").responses.find { |rsp| rsp.name == "Success" }
163
+ size = 7
164
+ result = ApiSketch::ResponseRenderer.new([response.parameters.wrapped_body], response.parameters.body_container_type, size).to_h
165
+
166
+ expect(result.size).to eql size
167
+ result.each do |element|
168
+ expect(element["name"]).to be_instance_of(String)
169
+ expect(element["id"]).to be_kind_of(Numeric)
170
+ end
171
+ end
172
+ end
123
173
  end
124
174
 
125
175
 
@@ -135,4 +185,4 @@ describe ApiSketch::ResponseRenderer do
135
185
  end
136
186
  end
137
187
 
138
- end
188
+ end
data/spec/spec_helper.rb CHANGED
@@ -1 +1,3 @@
1
- require "api_sketch"
1
+ require "api_sketch"
2
+
3
+ Dir["./spec/support/**/*.rb"].sort.each { |f| require f }
@@ -0,0 +1,9 @@
1
+ shared_examples_for "supports shared blocks" do
2
+ it "should support shared blocks" do
3
+ ApiSketch::DSL.new.shared_block "test data" do
4
+ "test shared block data"
5
+ end
6
+
7
+ expect(subject.use_shared_block("test data")).to eql "test shared block data"
8
+ end
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api_sketch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Suhoviy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-03 00:00:00.000000000 Z
11
+ date: 2015-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mixlib-cli
@@ -118,8 +118,6 @@ extensions: []
118
118
  extra_rdoc_files: []
119
119
  files:
120
120
  - ".gitignore"
121
- - ".ruby-gemset"
122
- - ".ruby-version"
123
121
  - CHANGELOG.md
124
122
  - Gemfile
125
123
  - LICENSE.txt
@@ -127,15 +125,35 @@ files:
127
125
  - Rakefile
128
126
  - api_sketch.gemspec
129
127
  - bin/api_sketch
128
+ - examples/api_project/config/initializers/shared_blocks.rb
129
+ - examples/api_project/resources/places.rb
130
+ - examples/api_project/resources/users.rb
131
+ - examples/api_project/resources/users/points.rb
132
+ - examples/api_project/resources/users/points/stats.rb
130
133
  - lib/api_sketch.rb
131
134
  - lib/api_sketch/config.rb
132
135
  - lib/api_sketch/dsl.rb
136
+ - lib/api_sketch/dsl/attribute_parser.rb
137
+ - lib/api_sketch/dsl/attributes.rb
138
+ - lib/api_sketch/dsl/base.rb
139
+ - lib/api_sketch/dsl/complex_attribute_parser.rb
140
+ - lib/api_sketch/dsl/headers.rb
141
+ - lib/api_sketch/dsl/parameters.rb
142
+ - lib/api_sketch/dsl/responses.rb
133
143
  - lib/api_sketch/error.rb
134
144
  - lib/api_sketch/examples_server.rb
135
- - lib/api_sketch/generators.rb
145
+ - lib/api_sketch/generators/base.rb
146
+ - lib/api_sketch/generators/bootstrap.rb
136
147
  - lib/api_sketch/helpers.rb
137
148
  - lib/api_sketch/model.rb
138
- - lib/api_sketch/renderers.rb
149
+ - lib/api_sketch/model/attribute.rb
150
+ - lib/api_sketch/model/base.rb
151
+ - lib/api_sketch/model/header.rb
152
+ - lib/api_sketch/model/parameters.rb
153
+ - lib/api_sketch/model/resource.rb
154
+ - lib/api_sketch/model/response.rb
155
+ - lib/api_sketch/model/shared_block.rb
156
+ - lib/api_sketch/response_renderer.rb
139
157
  - lib/api_sketch/runner.rb
140
158
  - lib/api_sketch/templates/bootstrap/assets/fonts/glyphicons-halflings-regular.eot
141
159
  - lib/api_sketch/templates/bootstrap/assets/fonts/glyphicons-halflings-regular.svg
@@ -156,14 +174,22 @@ files:
156
174
  - lib/api_sketch/templates/bootstrap/assets/stylesheets/dashboard.css
157
175
  - lib/api_sketch/templates/bootstrap/resource.html.erb
158
176
  - lib/api_sketch/version.rb
177
+ - spec/lib/api_sketch/dsl/attribute_parser_spec.rb
178
+ - spec/lib/api_sketch/dsl/attributes_spec.rb
179
+ - spec/lib/api_sketch/dsl/complex_attribute_parser_spec.rb
180
+ - spec/lib/api_sketch/dsl/headers_spec.rb
181
+ - spec/lib/api_sketch/dsl/parameters_spec.rb
182
+ - spec/lib/api_sketch/dsl/responses_spec.rb
159
183
  - spec/lib/api_sketch/dsl_spec.rb
160
- - spec/lib/api_sketch/renderers_spec.rb
184
+ - spec/lib/api_sketch/model/parameters_spec.rb
185
+ - spec/lib/api_sketch/response_renderer_spec.rb
161
186
  - spec/spec_helper.rb
187
+ - spec/support/shared_examples.rb
162
188
  homepage: https://github.com/suhovius/api_sketch
163
189
  licenses:
164
190
  - MIT
165
191
  metadata: {}
166
- post_install_message: Thanks for installing!
192
+ post_install_message:
167
193
  rdoc_options: []
168
194
  require_paths:
169
195
  - lib
@@ -184,6 +210,14 @@ signing_key:
184
210
  specification_version: 4
185
211
  summary: API Prototyping and API Documentation Tool
186
212
  test_files:
213
+ - spec/lib/api_sketch/dsl/attribute_parser_spec.rb
214
+ - spec/lib/api_sketch/dsl/attributes_spec.rb
215
+ - spec/lib/api_sketch/dsl/complex_attribute_parser_spec.rb
216
+ - spec/lib/api_sketch/dsl/headers_spec.rb
217
+ - spec/lib/api_sketch/dsl/parameters_spec.rb
218
+ - spec/lib/api_sketch/dsl/responses_spec.rb
187
219
  - spec/lib/api_sketch/dsl_spec.rb
188
- - spec/lib/api_sketch/renderers_spec.rb
220
+ - spec/lib/api_sketch/model/parameters_spec.rb
221
+ - spec/lib/api_sketch/response_renderer_spec.rb
189
222
  - spec/spec_helper.rb
223
+ - spec/support/shared_examples.rb
data/.ruby-gemset DELETED
@@ -1 +0,0 @@
1
- api_sketch
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- ruby-2.1.2