grape-apiary 0.0.2 → 0.0.3

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.
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