grape-apiary 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 52206e764a472e2d8f633d64fd3bbc539cc88925
4
- data.tar.gz: d8d6e2db710aa896c9803109eac91a3642800d88
3
+ metadata.gz: 4b15d2669d75c2f5461216dc111cb0680cf4ef03
4
+ data.tar.gz: 7fae72c31f7d7b15050f170af438bae065fd62e2
5
5
  SHA512:
6
- metadata.gz: d9980ad74abc11410812d277ef93358bc28d977b378b63f82f0f9164a9c81a50e4581b4aef331329519f87ef52ffae3ddf4e5df50338555b0af42b3dfbf4a987
7
- data.tar.gz: 4327574f995b557a30c69d9b2f5f193c0820cfc975c3ce72f697e42fde054ae3ce0a9e629b1b0b5cef71affa5611b2489766edbd6a5d803a1fc7721ee65d7b5a
6
+ metadata.gz: b746ab57f5703d7f0791a8c35bf257c9d2e87c8d9a8f2b5db4d347793a065e59b277a0bc1f16325dded4c03f80d8488afbab340bfbc0859150029b15b9643c07
7
+ data.tar.gz: 33f12c650f2518b7c5fb0570278bb70f4e684d5f524091862e73a3554884823d4b9763ad733d92b36d3f9e6ba85c415137aeae605cd38e0b344c387842940a8c
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format=progress
@@ -4,7 +4,7 @@ rvm:
4
4
  - 2.1.0
5
5
  - 2.0.0
6
6
  - 1.9.3
7
- - jruby-19mode
7
+ - jruby
8
8
  addons:
9
9
  code_climate:
10
10
  repo_token: acf391ea515caa468e74c55532dddebed1e1d32b235bee0845e04700e8c634aa
data/Gemfile CHANGED
@@ -2,3 +2,17 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in grape-apiary.gemspec
4
4
  gemspec
5
+
6
+ gem 'grape', github: 'intridea/grape'
7
+
8
+ group :development, :test do
9
+ gem 'coveralls', '~> 0.7'
10
+ gem 'rspec', '~> 2.14'
11
+ gem 'bundler', '~> 1.5'
12
+ gem 'rake', '~> 10.0'
13
+ gem 'rubocop', '~> 0.18'
14
+ gem 'pry', '~> 0.9'
15
+ gem 'guard', '~> 2.4'
16
+ gem 'guard-rspec', '~> 4.2'
17
+ gem 'guard-bundler', '~> 2.0'
18
+ end
@@ -0,0 +1,12 @@
1
+ # More info at https://github.com/guard/guard#readme
2
+
3
+ guard 'rspec', :version => 2 do
4
+ watch(%r{^spec/.+_spec\.rb$})
5
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
6
+ watch('spec/spec_helper.rb') { "spec/" }
7
+ end
8
+
9
+ guard 'bundler' do
10
+ watch('Gemfile')
11
+ watch(/^.+\.gemspec/)
12
+ end
data/README.md CHANGED
@@ -6,12 +6,17 @@
6
6
  [![Dependency Status](https://gemnasium.com/connexio-labs/grape-apiary.png)](https://gemnasium.com/connexio-labs/grape-apiary)
7
7
  [![Gem Version](https://badge.fury.io/rb/grape-apiary.png)](http://badge.fury.io/rb/grape-apiary)
8
8
 
9
- Auto generates an [Apiary Blueprint](http://apiary.io) from the docuementation that is created by your Grape API.
9
+ Auto generates an [Apiary Blueprint](http://apiary.io) from the docuementation that is created by your [Grape](https://github.com/intridea/grape) API.
10
+
11
+ ### NOTE
12
+
13
+ This is an early implementation that makes some assumptions about your API (follows a standard REST pattern) that works with our implementation of Grape API's. There is a new an [unreleased feature in Grape](https://github.com/intridea/grape#parameter-documentation) that allows for appending additional documentation. This project is dependent on this feature in order to create example JSON requests and responses.
10
14
 
11
15
  ## Installation
12
16
 
13
17
  Add this line to your application's Gemfile:
14
18
 
19
+ gem 'grape', github: 'intridea/grape' # see note above
15
20
  gem 'grape-apiary'
16
21
 
17
22
  And then execute:
@@ -24,9 +29,11 @@ Or install it yourself as:
24
29
 
25
30
  ## Usage
26
31
 
32
+ Add some metadata about your API and then execute the `generate` method on the `GrapeApiary::Blueprint` class.
33
+
27
34
  ### Configuration
28
35
 
29
- Configure details about your api in an initializers or similar
36
+ Configure details about your api in an initializers or similar:
30
37
 
31
38
  ```ruby
32
39
  GrapeApiary.config do |config|
@@ -36,21 +43,22 @@ GrapeApiary.config do |config|
36
43
  config.name = 'Awesome API'
37
44
  # a description for your api
38
45
  config.description = 'The awesome description'
46
+ # the type to use for generated sample id's (`integer` or `uuid`)
47
+ config.example_id_type = :uuid
39
48
  # resources you do not want documented
40
49
  config.resource_exclusion = [:admin, :swagger_doc]
41
50
  end
42
51
 
43
- # headers you want documented
52
+ # request headers you want documented
44
53
  GrapeApiary.config.request_headers = [
45
54
  { 'Accept-Charset' => 'utf-8' },
46
- { 'Connection' => 'keep-alive' },
47
- { 'Content-Type' => 'application/json' }
55
+ { 'Connection' => 'keep-alive' }
48
56
  ]
49
57
 
58
+ # response headers you want documented
50
59
  GrapeApiary.config.response_headers = [
51
60
  { 'Content-Length' => '21685' },
52
- { 'Connection' => 'keep-alive' },
53
- { 'Content-Type' => 'application/json' }
61
+ { 'Connection' => 'keep-alive' }
54
62
  ]
55
63
  ```
56
64
 
@@ -63,6 +71,12 @@ GrapeApiary::Blueprint.new(AwesomeAPI).generate
63
71
 
64
72
  ## TODO
65
73
 
74
+ * Add a rake task to simplify generation
75
+ * Add support for listing all of a resources attributes at the resource level as a markdown table
76
+ * Handle ever changing sample id's (don't want git diff's after every generation)
77
+ * Add option to change or remove the sample id field (eg. `_id` vs `id`)
78
+ * What if someone does not use JSON?!?
79
+ * Creat sample response for list endpoints (array)
66
80
 
67
81
  ## Contributing
68
82
 
data/Rakefile CHANGED
@@ -1,4 +1,8 @@
1
- require 'bundler/gem_tasks'
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup :default, :test, :development
4
+
5
+ Bundler::GemHelper.install_tasks
2
6
 
3
7
  require 'rspec/core/rake_task'
4
8
  RSpec::Core::RakeTask.new(:spec) do |spec|
@@ -26,4 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency 'rake', '~> 10.0'
27
27
  spec.add_development_dependency 'rubocop', '~> 0.18'
28
28
  spec.add_development_dependency 'pry', '~> 0.9'
29
+ spec.add_development_dependency 'guard', '~> 2.4'
30
+ spec.add_development_dependency 'guard-rspec', '~> 4.2'
31
+ spec.add_development_dependency 'guard-bundler', '~> 2.0'
29
32
  end
@@ -5,7 +5,6 @@ require 'grape-apiary/parameter'
5
5
  require 'grape-apiary/sample_generator'
6
6
  require 'grape-apiary/route'
7
7
  require 'grape-apiary/resource'
8
- require 'grape-apiary/routes'
9
8
  require 'grape-apiary/blueprint'
10
9
 
11
10
  module GrapeApiary
@@ -15,3 +14,15 @@ module GrapeApiary
15
14
  block_given? ? yield(Config) : Config
16
15
  end
17
16
  end
17
+
18
+ class UnsupportedIDType < StandardError
19
+ def message
20
+ 'Unsupported id type, supported types are [integer, uuid, bson]'
21
+ end
22
+ end
23
+
24
+ class BSONNotDefinied < StandardError
25
+ def message
26
+ 'BSON type id requested but bson library is not present'
27
+ end
28
+ end
@@ -1,11 +1,11 @@
1
1
  module GrapeApiary
2
2
  class Blueprint
3
- attr_reader :api_class, :template, :binding
3
+ attr_reader :api_class, :template
4
+
5
+ delegate(*GrapeApiary::Config::SETTINGS, to: 'GrapeApiary::Config')
4
6
 
5
7
  def initialize(api_class)
6
8
  @api_class = api_class
7
- @template = File.read('./lib/grape-apiary/templates/blueprint.md.erb')
8
- @binding = Routes.new(api_class).routes_binding
9
9
  end
10
10
 
11
11
  def generate
@@ -13,6 +13,62 @@ module GrapeApiary
13
13
  end
14
14
 
15
15
  def write
16
+ fail 'Not yet supported'
17
+ end
18
+
19
+ def template
20
+ @template ||= begin
21
+ directory = File.dirname(File.expand_path(__FILE__))
22
+ path = File.join(directory, './templates/blueprint.md.erb')
23
+
24
+ File.read(path)
25
+ end
26
+ end
27
+
28
+ def routes
29
+ @routes ||= api_class.routes.map do |route|
30
+ GrapeApiary::Route.new(route)
31
+ end
32
+ end
33
+
34
+ def resources
35
+ @resources ||= begin
36
+ grouped_routes = routes.group_by(&:route_name).reject do |name, routes|
37
+ resource_exclusion.include?(name.to_sym)
38
+ end
39
+
40
+ grouped_routes.map { |name, routes| Resource.new(name, routes) }
41
+ end
42
+ end
43
+
44
+ def formatted_request_headers
45
+ formatted_headers(GrapeApiary::Config.request_headers)
46
+ end
47
+
48
+ def formatted_response_headers
49
+ formatted_headers(GrapeApiary::Config.response_headers)
50
+ end
51
+
52
+ def show_request_sample?(route)
53
+ %w(PUT POST).include?(route.route_method)
54
+ end
55
+
56
+ def routes_binding
57
+ binding
58
+ end
59
+
60
+ private
61
+
62
+ def formatted_headers(headers)
63
+ spacer = "\n" + (' ' * 12)
64
+
65
+ strings = headers.map do |header|
66
+ key, value = *header.first
67
+
68
+ "#{key}: #{value}"
69
+ end
70
+
71
+ strings.join(spacer)
16
72
  end
17
73
  end
18
74
  end
@@ -6,6 +6,7 @@ module GrapeApiary
6
6
  :description,
7
7
  :request_headers,
8
8
  :response_headers,
9
+ :example_id_type,
9
10
  :resource_exclusion
10
11
  ]
11
12
 
@@ -23,6 +24,35 @@ module GrapeApiary
23
24
  def resource_exclusion
24
25
  @resource_exclusion ||= []
25
26
  end
27
+
28
+ def supported_id_types
29
+ [:integer, :uuid, :bson]
30
+ end
31
+
32
+ def example_id_type=(value)
33
+ fail UnsupportedIDType unless supported_id_types.include?(value)
34
+
35
+ if value.to_sym == :bson && !Object.const_defined?('BSON')
36
+ fail BSONNotDefinied
37
+ end
38
+
39
+ @example_id_type = value
40
+ end
41
+
42
+ def example_id_type
43
+ @example_id_type ||= :integer
44
+ end
45
+
46
+ def generate_id
47
+ case example_id_type
48
+ when :integer
49
+ SecureRandom.random_number(1000)
50
+ when :uuid
51
+ SecureRandom.uuid
52
+ when :bson
53
+ BSON::ObjectId.new.to_s
54
+ end
55
+ end
26
56
  end
27
57
  end
28
58
  end
@@ -2,8 +2,9 @@ module GrapeApiary
2
2
  class Parameter
3
3
  attr_reader :route, :name, :settings
4
4
 
5
- delegate :route_model, :route_namespace, to: :route
6
- delegate :requirement, :type, :example, :desc, to: :settings
5
+ delegate :route_model, :route_namespace, to: :route
6
+ delegate :requirement, :type, :documentation, :desc, to: :settings
7
+ delegate :example, to: :documentation, allow_nil: true
7
8
 
8
9
  def initialize(route, name, options)
9
10
  @route = route
@@ -30,11 +31,13 @@ module GrapeApiary
30
31
  model = name.include?('_id') ? name.gsub('_id', '') : route.route_model
31
32
 
32
33
  {
33
- required: true,
34
- requirement: 'required',
35
- type: 'uuid',
36
- desc: "the `id` of the `#{model}`",
37
- example: SecureRandom.uuid
34
+ required: true,
35
+ requirement: 'required',
36
+ type: 'uuid',
37
+ desc: "the `id` of the `#{model}`",
38
+ documentation: {
39
+ example: GrapeApiary::Config.generate_id
40
+ }
38
41
  }
39
42
  end
40
43
  end
@@ -1,11 +1,12 @@
1
1
  module GrapeApiary
2
2
  class Resource
3
- attr_reader :key, :name, :routes
3
+ attr_reader :key, :name, :routes, :sample_generator
4
4
 
5
5
  def initialize(key, routes)
6
- @key = key
7
- @name = key.humanize
8
- @routes = routes
6
+ @key = key
7
+ @name = key.humanize
8
+ @routes = routes
9
+ @sample_generator = SampleGenerator.new(self)
9
10
  end
10
11
 
11
12
  def title
@@ -32,15 +33,25 @@ module GrapeApiary
32
33
  end
33
34
 
34
35
  def sample_request
35
- SampleGenerator.new(self).request
36
+ sample_generator.request
36
37
  end
37
38
 
38
39
  def sample_response
39
- SampleGenerator.new(self).response
40
+ sample_generator.response
40
41
  end
41
42
 
42
43
  def unique_params
43
- # params = routes.map(&:route_params)
44
+ # TODO: this is a hack, assuming that the resource has a POST or PUT
45
+ # route that defines all of the parameters that would define the resource
46
+ potential = routes.select do |route|
47
+ %w(POST PUT).include?(route.route_method)
48
+ end
49
+
50
+ if potential.present?
51
+ potential.first.route_params
52
+ else
53
+ []
54
+ end
44
55
  end
45
56
  end
46
57
  end
@@ -2,19 +2,45 @@ module GrapeApiary
2
2
  class SampleGenerator
3
3
  attr_reader :resource
4
4
 
5
+ delegate :unique_params, to: :resource
6
+
5
7
  def initialize(resource)
6
8
  @resource = resource
7
9
  end
8
10
 
9
11
  def sample
12
+ @sample ||= begin
13
+ array = resource.unique_params.map do |resource|
14
+ [resource.name, resource.example]
15
+ end
16
+
17
+ Hash[array]
18
+ end
10
19
  end
11
20
 
12
21
  def request
13
- {}.to_json
22
+ return unless sample.present?
23
+
24
+ # format json spaces for blueprint markdown
25
+ JSON.pretty_generate(sample)
26
+ .gsub('{', (' ' * 14) + '{')
27
+ .gsub('}', (' ' * 14) + '}')
28
+ .gsub(/\ {2}\"/, (' ' * 16) + '"')
14
29
  end
15
30
 
16
31
  def response
17
- {}.to_json
32
+ return unless sample.present?
33
+
34
+ hash = sample.reverse_merge(id: GrapeApiary::Config.generate_id)
35
+ # sample = [sample] if list?(route)
36
+
37
+ # format json spaces for blueprint markdown
38
+ JSON.pretty_generate(hash)
39
+ .gsub('[', (' ' * 12) + '[')
40
+ .gsub(']', (' ' * 12) + ']')
41
+ .gsub('{', (' ' * 14) + '{')
42
+ .gsub('}', (' ' * 14) + '}')
43
+ .gsub(/\ {2}\"/, (' ' * 16) + '"')
18
44
  end
19
45
  end
20
46
  end
@@ -27,11 +27,14 @@ Actions on the <%= resource.name %> resource
27
27
 
28
28
  <%= resource.sample_request %>
29
29
  <% end %>
30
+ <%= route.request_description %>
30
31
  + Headers
31
32
 
32
33
  <%= formatted_response_headers %>
33
34
 
34
35
  + Body
36
+
37
+ <%= resource.sample_response %>
35
38
  <% end %>
36
39
  <% end %>
37
40
  <% end %>
@@ -1,3 +1,3 @@
1
1
  module GrapeApiary
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -3,26 +3,28 @@ require 'spec_helper'
3
3
  describe GrapeApiary::Blueprint do
4
4
  include_context 'configuration'
5
5
 
6
- context '#generate' do
7
- before do
8
- GrapeApiary.config do |config|
9
- config.host = host
10
- config.name = name
11
- config.description = description
12
- config.resource_exclusion = [:admin]
13
- end
6
+ before do
7
+ GrapeApiary.config do |config|
8
+ config.host = host
9
+ config.name = name
10
+ config.description = description
11
+ config.resource_exclusion = [:admin]
12
+ end
14
13
 
15
- GrapeApiary.config.request_headers = [
16
- { 'Accept-Charset' => 'utf-8' },
17
- { 'Connection' => 'keep-alive' }
18
- ]
14
+ GrapeApiary.config.request_headers = [
15
+ { 'Accept-Charset' => 'utf-8' },
16
+ { 'Connection' => 'keep-alive' }
17
+ ]
19
18
 
20
- GrapeApiary.config.response_headers = [
21
- { 'Content-Length' => '21685' },
22
- { 'Connection' => 'keep-alive' }
23
- ]
24
- end
19
+ GrapeApiary.config.response_headers = [
20
+ { 'Content-Length' => '21685' },
21
+ { 'Connection' => 'keep-alive' }
22
+ ]
23
+ end
24
+
25
+ subject { GrapeApiary::Blueprint.new(SampleApi) }
25
26
 
27
+ context '#generate' do
26
28
  let(:klass) { SampleApi }
27
29
 
28
30
  subject { GrapeApiary::Blueprint.new(klass).generate }
@@ -47,4 +49,32 @@ describe GrapeApiary::Blueprint do
47
49
  expect(subject).to include('# Group Widgets')
48
50
  end
49
51
  end
52
+
53
+ it 'exposes configuration settings' do
54
+ GrapeApiary::Config::SETTINGS.each do |setting|
55
+ expect(subject.send(setting)).to eq(GrapeApiary.config.send(setting))
56
+ end
57
+ end
58
+
59
+ it 'exposes the raw routes of the given api' do
60
+ expect(subject.routes).to eq(SampleApi.routes)
61
+ end
62
+
63
+ context '#resources' do
64
+ let(:unique_routes) { subject.routes.map(&:route_name).uniq }
65
+
66
+ let(:included_routes) do
67
+ unique_routes.reject do |name|
68
+ GrapeApiary.config.resource_exclusion.include?(name.to_sym)
69
+ end
70
+ end
71
+
72
+ it 'aggregates routes into resources' do
73
+ expect(subject.resources.first).to be_a(GrapeApiary::Resource)
74
+ end
75
+
76
+ it 'excluded resources based on configuration' do
77
+ expect(subject.resources.map(&:key)).to eq(included_routes)
78
+ end
79
+ end
50
80
  end
@@ -48,4 +48,38 @@ describe GrapeApiary::Config do
48
48
  end
49
49
  end
50
50
  end
51
+
52
+ context 'sample id generation' do
53
+ it 'allows for setting the type for id generation' do
54
+ subject.example_id_type = :uuid
55
+
56
+ expect(subject.example_id_type).to eq(:uuid)
57
+ end
58
+
59
+ it 'guards against unsupported types' do
60
+ expect do
61
+ subject.example_id_type = :foo
62
+ end.to raise_error(UnsupportedIDType)
63
+ end
64
+
65
+ it 'checks for the bson library if requested' do
66
+ expect { subject.example_id_type = :bson }.to raise_error(BSONNotDefinied)
67
+ end
68
+
69
+ it 'generates a valid uuid' do
70
+ test = /[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}/i
71
+
72
+ subject.example_id_type = :uuid
73
+
74
+ expect(subject.generate_id).to match(test)
75
+ end
76
+
77
+ it 'generates a valid integer' do
78
+ test = /^[0-9]{1,10}$/
79
+
80
+ subject.example_id_type = :integer
81
+
82
+ expect(subject.generate_id.to_s).to match(test)
83
+ end
84
+ end
51
85
  end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe GrapeApiary::Resource do
4
+ include_context 'configuration'
5
+
6
+ subject { GrapeApiary::Resource.new('foo', []) }
7
+
8
+ context 'sample' do
9
+ it 'request generation is delegated to a generator' do
10
+ expect(subject.sample_generator).to receive(:request)
11
+
12
+ subject.sample_request
13
+ end
14
+
15
+ it 'response generation is delegated to a generator' do
16
+ expect(subject.sample_generator).to receive(:response)
17
+
18
+ subject.sample_response
19
+ end
20
+ end
21
+ end
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe GrapeApiary::Route do
4
4
  include_context 'configuration'
5
5
 
6
- let(:routes) { GrapeApiary::Routes.new(SampleApi).routes }
6
+ let(:routes) { GrapeApiary::Blueprint.new(SampleApi).routes }
7
7
 
8
8
  subject { routes.first }
9
9
 
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe GrapeApiary::SampleGenerator do
4
+ include_context 'configuration'
5
+
6
+ before do
7
+ GrapeApiary.config do |config|
8
+ config.host = host
9
+ config.name = name
10
+ config.description = description
11
+ end
12
+ end
13
+
14
+ let(:blueprint) { GrapeApiary::Blueprint.new(SampleApi) }
15
+ let(:resource) { blueprint.resources.first }
16
+
17
+ subject { GrapeApiary::SampleGenerator.new(resource) }
18
+
19
+ it 'creates a sample hash from a resource' do
20
+ expect(subject.sample).to be_a(Hash)
21
+ end
22
+
23
+ context '#request' do
24
+ it 'creates a sample request in JSON form' do
25
+ expect { JSON.parse(subject.request) }.to_not raise_error
26
+ end
27
+ end
28
+
29
+ context '#response' do
30
+ it 'creates a sample response in JSON form' do
31
+ expect { JSON.parse(subject.response) }.to_not raise_error
32
+ end
33
+
34
+ it 'includes a sample id' do
35
+ expect(JSON.parse(subject.response)['id']).to_not be(nil)
36
+ end
37
+ end
38
+ end
@@ -1,13 +1,16 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'support'))
3
4
 
5
+ require 'grape/apiary'
6
+
7
+ require 'rubygems'
4
8
  require 'bundler'
5
9
  Bundler.setup :default, :test
6
10
 
7
11
  require 'coveralls'
8
12
  Coveralls.wear!
9
13
 
10
- require 'grape/apiary'
11
14
  require 'rspec'
12
15
  require 'pry'
13
16
 
@@ -5,24 +5,10 @@ shared_context 'configuration' do
5
5
  let(:resource_exclusion) { [:admin, :swagger_docs] }
6
6
 
7
7
  let(:request_headers) do
8
- [
9
- { 'Accept-Charset' => 'utf-8' },
10
- { 'Connection' => 'keep-alive' },
11
- { 'Content-Type' => 'application/json' }
12
- ]
8
+ [{ 'Accept-Charset' => 'utf-8' }]
13
9
  end
14
10
 
15
11
  let(:response_headers) do
16
- [
17
- { 'Content-Length' => '21685' },
18
- { 'Connection' => 'keep-alive' },
19
- { 'Content-Type' => 'application/json' }
20
- ]
21
- end
22
-
23
- let(:app) do
24
- def app
25
- SampleApi
26
- end
12
+ [{ 'Connection' => 'keep-alive' }]
27
13
  end
28
14
  end
@@ -10,8 +10,14 @@ class SampleApi < Grape::API
10
10
 
11
11
  desc 'create a widget'
12
12
  params do
13
- requires :name, type: 'string', desc: 'the widgets name'
14
- optional :description, type: 'string', desc: 'the widgets name'
13
+ requires :name,
14
+ type: 'string',
15
+ desc: 'the widgets name',
16
+ documentation: { example: 'super widget' }
17
+ optional :description,
18
+ type: 'string',
19
+ desc: 'the widgets name',
20
+ documentation: { example: 'the best widget ever made' }
15
21
  end
16
22
  post '/' do
17
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-apiary
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Allen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-06 00:00:00.000000000 Z
11
+ date: 2014-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grape
@@ -108,6 +108,48 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0.9'
111
+ - !ruby/object:Gem::Dependency
112
+ name: guard
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.4'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2.4'
125
+ - !ruby/object:Gem::Dependency
126
+ name: guard-rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '4.2'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '4.2'
139
+ - !ruby/object:Gem::Dependency
140
+ name: guard-bundler
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '2.0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '2.0'
111
153
  description: Auto generates an Apiary (http://apiary.io) Blueprint from the docuementation
112
154
  that is created by your Grape API
113
155
  email:
@@ -117,9 +159,11 @@ extensions: []
117
159
  extra_rdoc_files: []
118
160
  files:
119
161
  - ".gitignore"
162
+ - ".rspec"
120
163
  - ".rubocop.yml"
121
164
  - ".travis.yml"
122
165
  - Gemfile
166
+ - Guardfile
123
167
  - LICENSE.txt
124
168
  - README.md
125
169
  - Rakefile
@@ -130,15 +174,15 @@ files:
130
174
  - lib/grape-apiary/parameter.rb
131
175
  - lib/grape-apiary/resource.rb
132
176
  - lib/grape-apiary/route.rb
133
- - lib/grape-apiary/routes.rb
134
177
  - lib/grape-apiary/sample_generator.rb
135
178
  - lib/grape-apiary/templates/blueprint.md.erb
136
179
  - lib/grape-apiary/version.rb
137
180
  - lib/grape/apiary.rb
138
181
  - spec/grape-apiary/blueprint_spec.rb
139
182
  - spec/grape-apiary/config_spec.rb
183
+ - spec/grape-apiary/resource_spec.rb
140
184
  - spec/grape-apiary/route_spec.rb
141
- - spec/grape-apiary/routes_spec.rb
185
+ - spec/grape-apiary/sample_generator_spec.rb
142
186
  - spec/spec_helper.rb
143
187
  - spec/support/config_context.rb
144
188
  - spec/support/sample_api.rb
@@ -169,8 +213,9 @@ summary: Allows for generating an Apiary Blueprint for you Grape API
169
213
  test_files:
170
214
  - spec/grape-apiary/blueprint_spec.rb
171
215
  - spec/grape-apiary/config_spec.rb
216
+ - spec/grape-apiary/resource_spec.rb
172
217
  - spec/grape-apiary/route_spec.rb
173
- - spec/grape-apiary/routes_spec.rb
218
+ - spec/grape-apiary/sample_generator_spec.rb
174
219
  - spec/spec_helper.rb
175
220
  - spec/support/config_context.rb
176
221
  - spec/support/sample_api.rb
@@ -1,57 +0,0 @@
1
- module GrapeApiary
2
- class Routes
3
- attr_reader :api_class
4
-
5
- delegate(*GrapeApiary::Config::SETTINGS, to: 'GrapeApiary::Config')
6
-
7
- def initialize(api_class)
8
- @api_class = api_class
9
- end
10
-
11
- def routes
12
- @routes ||= api_class.routes.map do |route|
13
- GrapeApiary::Route.new(route)
14
- end
15
- end
16
-
17
- def resources
18
- @resources ||= begin
19
- grouped_routes = routes.group_by(&:route_name).reject do |name, routes|
20
- resource_exclusion.include?(name.to_sym)
21
- end
22
-
23
- grouped_routes.map { |name, routes| Resource.new(name, routes) }
24
- end
25
- end
26
-
27
- def formatted_request_headers
28
- formatted_headers(GrapeApiary::Config.request_headers)
29
- end
30
-
31
- def formatted_response_headers
32
- formatted_headers(GrapeApiary::Config.response_headers)
33
- end
34
-
35
- def show_request_sample?(route)
36
- %w(PUT POST).include?(route.route_method)
37
- end
38
-
39
- def routes_binding
40
- binding
41
- end
42
-
43
- private
44
-
45
- def formatted_headers(headers)
46
- spacer = "\n" + (' ' * 12)
47
-
48
- strings = headers.map do |header|
49
- key, value = *header.first
50
-
51
- "#{key}: #{value}"
52
- end
53
-
54
- strings.join(spacer)
55
- end
56
- end
57
- end
@@ -1,54 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe GrapeApiary::Routes do
4
- include_context 'configuration'
5
-
6
- before do
7
- GrapeApiary.config do |config|
8
- config.host = host
9
- config.name = name
10
- config.description = description
11
- config.resource_exclusion = [:admin]
12
- end
13
-
14
- GrapeApiary.config.request_headers = [
15
- { 'Accept-Charset' => 'utf-8' },
16
- { 'Connection' => 'keep-alive' }
17
- ]
18
-
19
- GrapeApiary.config.response_headers = [
20
- { 'Content-Length' => '21685' },
21
- { 'Connection' => 'keep-alive' }
22
- ]
23
- end
24
-
25
- subject { GrapeApiary::Routes.new(SampleApi) }
26
-
27
- it 'exposes configuration settings' do
28
- GrapeApiary::Config::SETTINGS.each do |setting|
29
- expect(subject.send(setting)).to eq(GrapeApiary.config.send(setting))
30
- end
31
- end
32
-
33
- it 'exposes the raw routes of the given api' do
34
- expect(subject.routes).to eq(SampleApi.routes)
35
- end
36
-
37
- context '#resources' do
38
- let(:unique_routes) { subject.routes.map(&:route_name).uniq }
39
-
40
- let(:included_routes) do
41
- unique_routes.reject do |name|
42
- GrapeApiary.config.resource_exclusion.include?(name.to_sym)
43
- end
44
- end
45
-
46
- it 'aggregates routes into resources' do
47
- expect(subject.resources.first).to be_a(GrapeApiary::Resource)
48
- end
49
-
50
- it 'excluded resources based on configuration' do
51
- expect(subject.resources.map(&:key)).to eq(included_routes)
52
- end
53
- end
54
- end