api_sketch 0.1.1 → 0.1.2

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