Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More API Blueprint fixes #2

Merged
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
doc
tmp
.rvmrc
.ruby-version
Expand Down
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ GEM
multipart-post (>= 1.2, < 3)
ffi (1.9.10)
gherkin (3.2.0)
hashdiff (0.2.3)
hashdiff (0.3.7)
httpclient (2.7.1)
i18n (0.7.0)
inch (0.7.0)
Expand Down Expand Up @@ -129,7 +129,7 @@ GEM
tins (1.8.2)
tzinfo (1.2.2)
thread_safe (~> 0.1)
webmock (1.22.6)
webmock (3.3.0)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff
Expand All @@ -154,7 +154,7 @@ DEPENDENCIES
rspec_api_documentation!
sinatra (~> 1.4, >= 1.4.4)
thin (~> 1.6, >= 1.6.3)
webmock (~> 1.7)
webmock (~> 3.3)

BUNDLED WITH
1.16.1
16 changes: 12 additions & 4 deletions lib/rspec_api_documentation/dsl/endpoint/params.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,19 @@ def initialize(example_group, example, extra_params)
end

def call
parameters = example.metadata.fetch(:parameters, {}).inject({}) do |hash, param|
set_param = -> hash, param {
SetParam.new(self, hash, param).call
end
parameters.deep_merge!(extra_params)
parameters
}

example.metadata
.fetch(:parameters, {})
.inject({}, &set_param)
.deep_merge(
example.metadata
.fetch(:attributes, {})
.inject({}, &set_param)
)
.deep_merge(extra_params)
end

private
Expand Down
10 changes: 8 additions & 2 deletions lib/rspec_api_documentation/dsl/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def self.define_action(method)

def callback(*args, &block)
begin
require 'webmock'
require 'webmock/rspec'
rescue LoadError
raise "Callbacks require webmock to be installed"
end
Expand Down Expand Up @@ -71,7 +71,13 @@ def header(name, value)
end

def explanation(text)
safe_metadata(:resource_explanation, text)
if metadata[:method].present?
safe_metadata(:method_explanation, text)
elsif metadata[:route_uri].present?
safe_metadata(:route_explanation, text)
else
safe_metadata(:resource_explanation, text)
end
end

private
Expand Down
11 changes: 7 additions & 4 deletions lib/rspec_api_documentation/views/api_blueprint_index.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ def sections
methods = examples.group_by(&:http_method).map do |http_method, examples|
{
http_method: http_method,
description: examples.first.respond_to?(:action_name) && examples.first.action_name,
description: examples.first.try(:action_name),
explanation: examples.first.try(:[], :metadata).try(:[], :method_explanation),
examples: examples
}
end
Expand All @@ -25,6 +26,7 @@ def sections
"has_parameters?".to_sym => params.size > 0,
route: format_route(examples[0]),
route_name: examples[0][:route_name],
explanation: examples[0][:route_explanation],
attributes: attrs,
parameters: params,
http_methods: methods
Expand Down Expand Up @@ -60,11 +62,10 @@ def format_route(example)
# with all of its properties, like name, description, required.
# {
# required: true,
# example: "1",
# type: "string",
# name: "id",
# description: "The id",
# properties_description: "required, string"
# properties_description: "string, required"
# }
def fields(property_name, examples)
examples
Expand All @@ -74,8 +75,10 @@ def fields(property_name, examples)
.uniq { |property| property[:name] }
.map do |property|
properties = []
properties << "required" if property[:required]
properties << property[:type] if property[:type]
properties << "required" if property[:required] == true
properties << "optional" if property[:required].blank?

if properties.count > 0
property[:properties_description] = properties.join(", ")
else
Expand Down
2 changes: 1 addition & 1 deletion rspec_api_documentation.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Gem::Specification.new do |s|
s.add_development_dependency "rake", "~> 10.1"
s.add_development_dependency "rack-test", "~> 0.6.2"
s.add_development_dependency "rack-oauth2", "~> 1.2.2", ">= 1.0.7"
s.add_development_dependency "webmock", "~> 1.7"
s.add_development_dependency "webmock", "~> 3.3"
s.add_development_dependency "rspec-its", "~> 1.0"
s.add_development_dependency "faraday", "~> 0.9", ">= 0.9.0"
s.add_development_dependency "thin", "~> 1.6", ">= 1.6.3"
Expand Down
7 changes: 7 additions & 0 deletions spec/dsl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,12 @@
parameter :id, 'The ID of the resource.', :required => true, scope: :data
parameter :note, "Any additional notes about your order."

attribute :tip, "The amount you want to tip", :required => true

let(:type) { "coffee" }
let(:size) { "medium" }
let(:data_id) { 2 }
let(:tip) { 20 }

let(:id) { 1 }

Expand All @@ -157,6 +160,10 @@
expect(params['data']).to eq({'id' => 2})
end

it "should set attributes as well" do
expect(params["tip"]).to eq(tip())
end

it "should allow extra parameters to be passed in" do
expect(client).to receive(method).with(path, params.merge("extra" => true), nil)
do_request(:extra => true)
Expand Down
6 changes: 3 additions & 3 deletions spec/http_test_client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require 'capybara'
require 'capybara/server'
require 'sinatra/base'
require 'webmock'
require 'webmock/rspec'
require 'support/stub_app'

describe RspecApiDocumentation::HttpTestClient do
Expand All @@ -16,7 +16,7 @@
Rack::Handler::Thin.run(app, :Port => port)
end

server = Capybara::Server.new(StubApp.new, 8888)
server = Capybara::Server.new(StubApp.new, 29876)
server.boot
end

Expand All @@ -25,7 +25,7 @@
end

let(:client_context) { |example| double(example: example, app_root: 'nowhere') }
let(:target_host) { 'http://localhost:8888' }
let(:target_host) { 'http://localhost:29876' }
let(:test_client) { RspecApiDocumentation::HttpTestClient.new(client_context, {host: target_host}) }

subject { test_client }
Expand Down
13 changes: 9 additions & 4 deletions spec/views/api_blueprint_index_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@

let(:rspec_example_comments) do
comment_group.route "/comments", "Comments Collection" do
explanation "Route explanation"

get("/comments") do
explanation "Method explanation"
example_request 'Get all comments' do
end
end
Expand Down Expand Up @@ -98,6 +101,8 @@
post_route = sections[1][:routes][1]
post_route_with_optionals = sections[1][:routes][2]

expect(comments_route[:explanation]).to eq "Route explanation"

comments_examples = comments_route[:http_methods].map { |http_method| http_method[:examples] }.flatten
expect(comments_examples.size).to eq 1
expect(comments_route[:route]).to eq "/comments"
Expand All @@ -118,7 +123,7 @@
example: "1",
name: "id",
description: "The id",
properties_description: "required, string"
properties_description: "string, required"
}]
expect(post_route[:has_attributes?]).to eq true
expect(post_route[:attributes]).to eq [{
Expand All @@ -139,11 +144,11 @@
example: "1",
name: "id",
description: "The id",
properties_description: "required, string"
properties_description: "string, required"
}, {
name: "option",
description: nil,
properties_description: nil
properties_description: "optional"
}]
expect(post_route_with_optionals[:has_attributes?]).to eq false
expect(post_route_with_optionals[:attributes]).to eq []
Expand All @@ -159,7 +164,7 @@
required: false,
name: "description",
description: nil,
properties_description: nil
properties_description: "optional"
}]
end
end
Expand Down
38 changes: 28 additions & 10 deletions templates/rspec_api_documentation/api_blueprint_index.mustache
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
FORMAT: 1A

# {{ api_name }}
{{{ api_explanation }}}

{{# sections }}

# Group {{ resource_name }}
Expand All @@ -16,34 +19,49 @@ FORMAT: 1A
## {{ route_name }} [{{ route }}]
{{# description }}

description: {{ description }}
{{ description }}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what value this should have... or if it even works.

Copy link

@yld yld Feb 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, thanks, we just need to add apiblueprint validations in spec suite, and we'll be done.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the specs, and added an expectation for the "route explanations". I can't seem to write an expectation for the "method explanations", although it works when I use the gem. Something seems off with the http_methods in the specs for some reason.

{{/ description }}
{{# explanation }}

explanation: {{ explanation }}
{{{ explanation }}}
{{/ explanation }}
{{# has_parameters? }}

+ Parameters

{{# parameters }}
+ {{ name }}{{# example }}: {{ example }}{{/ example }}{{# properties_description }} ({{ properties_description }}){{/ properties_description }}{{# description }} - {{ description }}{{/ description }}
+ {{ name }}{{# properties_description }} ({{ properties_description }}){{/ properties_description }}{{# description }} - {{ description }}{{/ description }}
{{/ parameters }}
{{/ has_parameters? }}
{{# http_methods }}

{{# examples }}
{{# requests }}

### {{ action_name }} [{{ http_method }}]
{{# explanation }}

{{{ explanation }}}
{{/ explanation }}
{{# has_attributes? }}

+ Attributes (object)
+ Parameters

{{# attributes }}
+ {{ name }}{{# example }}: {{ example }}{{/ example }}{{# properties_description }} ({{ properties_description }}){{/ properties_description }}{{# description }} - {{ description }}{{/ description }}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example is the RSpec example in this case, which we don't want. I wanted to render the actual value of the param here, but I don't think it's possible without some serious refactoring. I did add the ability to define the "default" though.

Anyhow, if you have an idea how we could get the actual parameter value in here that would be amazing 🙏

+ {{ name }}{{# value }}: {{ value }}{{/ value }}{{# properties_description }} ({{ properties_description }}){{/ properties_description }}{{# description }} - {{ description }}{{/ description }}
{{# default }}

+ Default: {{ default }}
{{/ default }}
{{/ attributes }}
{{/ has_attributes? }}
{{# http_methods }}

### {{ description }} [{{ http_method }}]
{{# examples }}
{{# requests }}
{{# has_request? }}

+ Request {{ description }}{{# request_content_type }} ({{ request_content_type }}){{/ request_content_type }}

{{# explanation }}
{{{ explanation }}}
{{/ explanation }}
{{/ has_request? }}
{{# request_headers_text }}

Expand Down