Skip to content

Another attempt at adding explanations to resources #269

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

Merged
merged 2 commits into from
Jun 23, 2016
Merged
Changes from all 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,6 +1,7 @@
tmp
.rvmrc
.ruby-version
.ruby-gemset
example/docs
example/public/docs
*.gem
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -369,6 +369,22 @@ resource "Orders" do
end
```

A resource can also have an explanation.

```ruby
resource "Orders" do
explanation "Orders are top-level business objects. They can be created by a POST request"
post "/orders" do
example "Creating an order" do
explanation "This method creates a new order."
do_request
# make assertions
end
end
end
```


#### header

This method takes the header name and value. The value can be a string or a symbol. If it is a symbol it will `send` the symbol, allowing you to `let` header values.
16 changes: 10 additions & 6 deletions features/combined_json.feature
Original file line number Diff line number Diff line change
@@ -29,23 +29,25 @@ Feature: Combined text
end
resource "Greetings" do
explanation "Welcome to the party"
get "/greetings" do
parameter :target, "The thing you want to greet"
example "Greeting your favorite gem" do
do_request :target => "rspec_api_documentation"
response_headers["Content-Type"].should eq("text/plain")
status.should eq(200)
response_body.should eq('Hello, rspec_api_documentation!')
expect(response_headers["Content-Type"]).to eq("text/plain")
expect(status).to eq(200)
expect(response_body).to eq('Hello, rspec_api_documentation!')
end
example "Greeting your favorite developers of your favorite gem" do
do_request :target => "Sam & Eric"
response_headers["Content-Type"].should eq("text/plain")
status.should eq(200)
response_body.should eq('Hello, Sam & Eric!')
expect(response_headers["Content-Type"]).to eq("text/plain")
expect(status).to eq(200)
expect(response_body).to eq('Hello, Sam & Eric!')
end
end
end
@@ -70,6 +72,7 @@ Feature: Combined text
[
{
"resource": "Greetings",
"resource_explanation": "Welcome to the party",
"http_method": "GET",
"route": "/greetings",
"description": "Greeting your favorite gem",
@@ -106,6 +109,7 @@ Feature: Combined text
},
{
"resource": "Greetings",
"resource_explanation": "Welcome to the party",
"http_method": "GET",
"route": "/greetings",
"description": "Greeting your favorite developers of your favorite gem",
13 changes: 6 additions & 7 deletions features/combined_text.feature
Original file line number Diff line number Diff line change
@@ -33,17 +33,17 @@ Feature: Combined text
example "Greeting your favorite gem" do
do_request :target => "rspec_api_documentation"
response_headers["Content-Type"].should eq("text/plain")
status.should eq(200)
response_body.should eq('Hello, rspec_api_documentation!')
expect(response_headers["Content-Type"]).to eq("text/plain")
expect(status).to eq(200)
expect(response_body).to eq('Hello, rspec_api_documentation!')
end
example "Greeting your favorite developers of your favorite gem" do
do_request :target => "Sam & Eric"
response_headers["Content-Type"].should eq("text/plain")
status.should eq(200)
response_body.should eq('Hello, Sam & Eric!')
expect(response_headers["Content-Type"]).to eq("text/plain")
expect(status).to eq(200)
expect(response_body).to eq('Hello, Sam & Eric!')
end
example "Multiple Requests" do
@@ -145,6 +145,5 @@ Feature: Combined text
Content-Type: text/plain
Hello, Eric!
"""

2 changes: 1 addition & 1 deletion features/curl.feature
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ Feature: cURL output
example "Getting Foo" do
do_request
response_body.should == "foo"
expect(response_body).to eq("foo")
end
end
end
2 changes: 1 addition & 1 deletion features/headers.feature
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ Feature: Specifying request headers
example "Getting Foo" do
do_request
response_body.should == "foo"
expect(response_body).to eq("foo")
end
end
end
6 changes: 3 additions & 3 deletions features/html_documentation.feature
Original file line number Diff line number Diff line change
@@ -36,9 +36,9 @@ Feature: Generate HTML documentation from test examples
example "Greeting your favorite gem" do
do_request :target => "rspec_api_documentation"
response_headers["Content-Type"].should eq("application/json")
status.should eq(200)
response_body.should eq('{"hello":"rspec_api_documentation"}')
expect(response_headers["Content-Type"]).to eq("application/json")
expect(status).to eq(200)
expect(response_body).to eq('{"hello":"rspec_api_documentation"}')
end
end
end
12 changes: 6 additions & 6 deletions features/json_iodocs.feature
Original file line number Diff line number Diff line change
@@ -35,17 +35,17 @@ Feature: Json Iodocs
example "Greeting your favorite gem" do
do_request :target => "rspec_api_documentation"
response_headers["Content-Type"].should eq("text/plain")
status.should eq(200)
response_body.should eq('Hello, rspec_api_documentation!')
expect(response_headers["Content-Type"]).to eq("text/plain")
expect(status).to eq(200)
expect(response_body).to eq('Hello, rspec_api_documentation!')
end
example "Greeting your favorite developers of your favorite gem" do
do_request :target => "Sam & Eric"
response_headers["Content-Type"].should eq("text/plain")
status.should eq(200)
response_body.should eq('Hello, Sam & Eric!')
expect(response_headers["Content-Type"]).to eq("text/plain")
expect(status).to eq(200)
expect(response_body).to eq('Hello, Sam & Eric!')
end
end
end
23 changes: 13 additions & 10 deletions features/markdown_documentation.feature
Original file line number Diff line number Diff line change
@@ -59,17 +59,17 @@ Feature: Generate Markdown documentation from test examples
response_field :page, "Current page"
example_request 'Getting a list of orders' do
status.should eq(200)
response_body.should eq('{"page":1,"orders":[{"name":"Order 1","amount":9.99,"description":null},{"name":"Order 2","amount":100.0,"description":"A great order"}]}')
expect(status).to eq(200)
expect(response_body).to eq('{"page":1,"orders":[{"name":"Order 1","amount":9.99,"description":null},{"name":"Order 2","amount":100.0,"description":"A great order"}]}')
end
end
get '/orders/:id' do
let(:id) { 1 }
example_request 'Getting a specific order' do
status.should eq(200)
response_body.should == '{"order":{"name":"Order 1","amount":100.0,"description":"A great order"}}'
expect(status).to eq(200)
expect(response_body).to eq('{"order":{"name":"Order 1","amount":100.0,"description":"A great order"}}')
end
end
@@ -82,7 +82,7 @@ Feature: Generate Markdown documentation from test examples
let(:amount) { 33.0 }
example_request 'Creating an order' do
status.should == 201
expect(status).to eq(201)
end
end
@@ -95,24 +95,26 @@ Feature: Generate Markdown documentation from test examples
let(:name) { "Updated name" }
example_request 'Updating an order' do
status.should == 200
expect(status).to eq(200)
end
end
delete "/orders/:id" do
let(:id) { 1 }
example_request "Deleting an order" do
status.should == 200
expect(status).to eq(200)
end
end
end
resource 'Help' do
explanation 'Getting help'
get '/help' do
example_request 'Getting welcome message' do
status.should eq(200)
response_body.should == 'Welcome Henry !'
expect(status).to eq(200)
expect(response_body).to eq('Welcome Henry !')
end
end
@@ -149,6 +151,8 @@ Feature: Generate Markdown documentation from test examples
## Help
Getting help
* [Getting welcome message](help/getting_welcome_message.markdown)
## Orders
@@ -212,7 +216,6 @@ Feature: Generate Markdown documentation from test examples
}
]
}</pre>
"""

Scenario: Example 'Creating an order' file should look like we expect
18 changes: 9 additions & 9 deletions features/oauth2_mac_client.feature
Original file line number Diff line number Diff line change
@@ -77,9 +77,9 @@ Feature: Use OAuth2 MAC client as a test client
example "Greeting your favorite gem" do
do_request :target => "rspec_api_documentation"
response_headers["Content-Type"].should eq("text/plain")
status.should eq(200)
response_body.should eq('hello rspec_api_documentation')
expect(response_headers["Content-Type"]).to eq("text/plain")
expect(status).to eq(200)
expect(response_body).to eq('hello rspec_api_documentation')
end
end
@@ -91,9 +91,9 @@ Feature: Use OAuth2 MAC client as a test client
example "Greeting your favorite people" do
do_request
response_headers["Content-Type"].should eq("text/plain")
status.should eq(200)
response_body.should eq("hello eric, sam")
expect(response_headers["Content-Type"]).to eq("text/plain")
expect(status).to eq(200)
expect(response_body).to eq("hello eric, sam")
end
end
@@ -105,9 +105,9 @@ Feature: Use OAuth2 MAC client as a test client
example "Greeting your favorite companies" do
do_request
response_headers["Content-Type"].should eq("text/plain")
status.should eq(200)
response_body.should eq("hello apple with mac and ios, google with search and mail")
expect(response_headers["Content-Type"]).to eq("text/plain")
expect(status).to eq(200)
expect(response_body).to eq("hello apple with mac and ios, google with search and mail")
end
end
2 changes: 1 addition & 1 deletion features/patch.feature
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ Feature: Example Request with PATCH
resource "Example Request" do
patch "/" do
example_request "Trying out patch" do
status.should eq(200)
expect(status).to eq(200)
end
end
end
4 changes: 2 additions & 2 deletions features/readme.md
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ See the wiki for additional setup. [Setting up RSpec API Documentation](https://
get "/accounts" do
example "Get a list of all accounts" do
do_request
last_response.status.should be_ok
expect(last_response.status).to be_ok
end
end

@@ -42,7 +42,7 @@ See the wiki for additional setup. [Setting up RSpec API Documentation](https://

example "Get an account", :document => :public do
do_request
last_response.status.should be_ok
expect(last_response.status).to be_ok
end
end
end
2 changes: 1 addition & 1 deletion features/redefining_client.feature
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ Feature: Redefining the client method
get "/" do
example_request "Trying out get" do
status.should eq(200)
expect(status).to eq(200)
end
end
end
24 changes: 14 additions & 10 deletions features/textile_documentation.feature
Original file line number Diff line number Diff line change
@@ -59,17 +59,17 @@ Feature: Generate Textile documentation from test examples
response_field :page, "Current page"
example_request 'Getting a list of orders' do
status.should eq(200)
response_body.should eq('{"page":1,"orders":[{"name":"Order 1","amount":9.99,"description":null},{"name":"Order 2","amount":100.0,"description":"A great order"}]}')
expect(status).to eq(200)
expect(response_body).to eq('{"page":1,"orders":[{"name":"Order 1","amount":9.99,"description":null},{"name":"Order 2","amount":100.0,"description":"A great order"}]}')
end
end
get '/orders/:id' do
let(:id) { 1 }
example_request 'Getting a specific order' do
status.should eq(200)
response_body.should == '{"order":{"name":"Order 1","amount":100.0,"description":"A great order"}}'
expect(status).to eq(200)
expect(response_body).to eq('{"order":{"name":"Order 1","amount":100.0,"description":"A great order"}}')
end
end
@@ -82,7 +82,7 @@ Feature: Generate Textile documentation from test examples
let(:amount) { 33.0 }
example_request 'Creating an order' do
status.should == 201
expect(status).to eq(201)
end
end
@@ -95,24 +95,26 @@ Feature: Generate Textile documentation from test examples
let(:name) { "Updated name" }
example_request 'Updating an order' do
status.should == 200
expect(status).to eq(200)
end
end
delete "/orders/:id" do
let(:id) { 1 }
example_request "Deleting an order" do
status.should == 200
expect(status).to eq(200)
end
end
end
resource 'Help' do
explanation 'Getting help'
get '/help' do
example_request 'Getting welcome message' do
status.should eq(200)
response_body.should == 'Welcome Henry !'
expect(status).to eq(200)
expect(response_body).to eq('Welcome Henry !')
end
end
@@ -149,6 +151,8 @@ Feature: Generate Textile documentation from test examples
h2. Help
Getting help
* "Getting welcome message":help/getting_welcome_message.textile
h2. Orders
@@ -160,7 +164,7 @@ Feature: Generate Textile documentation from test examples
* "Updating an order":orders/updating_an_order.textile
"""

Scenario: Example 'Getting al ist of orders' file should look like we expect
Scenario: Example 'Getting a list of orders' file should look like we expect
Then the file "doc/api/orders/getting_a_list_of_orders.textile" should contain exactly:
"""
h1. Orders API
8 changes: 4 additions & 4 deletions features/upload_file.feature
Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@ Feature: Uploading a file
end
example_request "Uploading a file" do
response_body.should == "file.txt"
expect(response_body).to eq("file.txt")
end
end
end
@@ -85,7 +85,7 @@ Feature: Uploading a file
end
example_request "Uploading a file" do
response_body.should == "file.txt"
expect(response_body).to eq("file.txt")
end
end
end
@@ -117,7 +117,7 @@ Feature: Uploading a file
end
example_request "Uploading a file" do
response_body.should == "file.png"
expect(response_body).to eq("file.png")
end
end
end
@@ -153,7 +153,7 @@ Feature: Uploading a file
end
example_request "Uploading a file" do
response_body.should == "file.png"
expect(response_body).to eq("file.png")
end
end
end
4 changes: 4 additions & 0 deletions lib/rspec_api_documentation/dsl/resource.rb
Original file line number Diff line number Diff line change
@@ -50,6 +50,10 @@ def header(name, value)
headers[name] = value
end

def explanation(text)
safe_metadata(:resource_explanation, text)
end

private

def field_specification(name, *args)
4 changes: 4 additions & 0 deletions lib/rspec_api_documentation/example.rb
Original file line number Diff line number Diff line change
@@ -42,6 +42,10 @@ def has_response_fields?
respond_to?(:response_fields) && response_fields.present?
end

def resource_explanation
metadata[:resource_explanation] || nil
end

def explanation
metadata[:explanation] || nil
end
2 changes: 1 addition & 1 deletion lib/rspec_api_documentation/writers/index_helper.rb
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ module IndexHelper
def sections(examples, configuration)
resources = examples.group_by(&:resource_name).inject([]) do |arr, (resource_name, examples)|
ordered_examples = configuration.keep_source_order ? examples : examples.sort_by(&:description)
arr.push(:resource_name => resource_name, :examples => ordered_examples)
arr.push(:resource_name => resource_name, :examples => ordered_examples, resource_explanation: examples.first.resource_explanation)
end
configuration.keep_source_order ? resources : resources.sort_by { |resource| resource[:resource_name] }
end
2 changes: 2 additions & 0 deletions lib/rspec_api_documentation/writers/json_writer.rb
Original file line number Diff line number Diff line change
@@ -47,6 +47,7 @@ def as_json(opts = nil)
def section_hash(section)
{
:name => section[:resource_name],
:explanation => section[:resource_explanation],
:examples => section[:examples].map { |example|
{
:description => example.description,
@@ -87,6 +88,7 @@ def filename
def as_json(opts = nil)
{
:resource => resource_name,
:resource_explanation => resource_explanation,
:http_method => http_method,
:route => route,
:description => description,
3 changes: 3 additions & 0 deletions spec/dsl_spec.rb
Original file line number Diff line number Diff line change
@@ -9,10 +9,13 @@
end

resource "Order" do
explanation "Order resource explanation"

describe "example metadata" do
subject { |example| example.metadata }

its([:resource_name]) { should eq("Order") }
its([:resource_explanation]) { should eq("Order resource explanation") }
its([:document]) { should be_truthy }
end

11 changes: 11 additions & 0 deletions spec/example_spec.rb
Original file line number Diff line number Diff line change
@@ -169,6 +169,17 @@
end
end

describe "#resource_explanation" do
it "should return the metadata resource_explanation" do
example.metadata[:resource_explanation] = "Here is a resource explanation"
expect(example.resource_explanation).to eq("Here is a resource explanation")
end

it "should return an empty string when not set" do
expect(example.resource_explanation).to eq(nil)
end
end

describe "#explanation" do
it "should return the metadata explanation" do
example.metadata[:explanation] = "Here is an explanation"
8 changes: 4 additions & 4 deletions spec/writers/index_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -2,10 +2,10 @@

describe RspecApiDocumentation::Writers::IndexHelper do
describe "#sections" do
let(:example_1) { double(:resource_name => "Order", :description => "Updating an order") }
let(:example_2) { double(:resource_name => "Order", :description => "Creating an order") }
let(:example_3) { double(:resource_name => "Cart", :description => "Creating an cart") }
let(:examples) { [example_1, example_2, example_3] }
let(:example_1) { double(:resource_name => "Order", :description => "Updating an order", resource_explanation: 'Resource explanation') }
let(:example_2) { double(:resource_name => "Order", :description => "Creating an order", resource_explanation: 'Resource explanation') }
let(:example_3) { double(:resource_name => "Cart", :description => "Creating an cart", resource_explanation: 'Resource explanation') }
let(:examples) { [example_1, example_2, example_3] }

context "with default value for keep_source_order" do
let(:configuration) { RspecApiDocumentation::Configuration.new }
4 changes: 4 additions & 0 deletions templates/rspec_api_documentation/html_example.mustache
Original file line number Diff line number Diff line change
@@ -10,6 +10,10 @@
<body>
<div class="container">
<h1>{{resource_name}} API</h1>
{{# resource_explanation }}

<p class="explanation">{{{ resource_explanation }}}</p>
{{/ resource_explanation }}

<div class="article">
<h2>{{ description }}</h2>
4 changes: 4 additions & 0 deletions templates/rspec_api_documentation/html_index.mustache
Original file line number Diff line number Diff line change
@@ -14,6 +14,10 @@
{{# sections }}
<div class="article">
<h2>{{ resource_name }}</h2>
{{# resource_explanation }}

<p class="explanation">{{{ resource_explanation }}}</p>
{{/ resource_explanation }}

<ul>
{{# examples }}
4 changes: 4 additions & 0 deletions templates/rspec_api_documentation/markdown_example.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# {{ resource_name }} API
{{# resource_explanation }}

{{{ resource_explanation }}}
{{/ resource_explanation }}

## {{ description }}

4 changes: 4 additions & 0 deletions templates/rspec_api_documentation/markdown_index.mustache
Original file line number Diff line number Diff line change
@@ -2,6 +2,10 @@

{{# sections }}
## {{ resource_name }}
{{# resource_explanation }}

{{{ resource_explanation }}}
{{/ resource_explanation }}

{{# examples }}
* [{{ description }}]({{ dirname }}/{{ filename }})
4 changes: 4 additions & 0 deletions templates/rspec_api_documentation/textile_example.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
h1. {{ resource_name }} API
{{# resource_explanation }}

{{{ resource_explanation }}}
{{/ resource_explanation }}

h2. {{ description }}

4 changes: 4 additions & 0 deletions templates/rspec_api_documentation/textile_index.mustache
Original file line number Diff line number Diff line change
@@ -2,6 +2,10 @@ h1. {{ api_name }}

{{# sections }}
h2. {{ resource_name }}
{{# resource_explanation }}

{{{ resource_explanation }}}
{{/ resource_explanation }}

{{# examples }}
* "{{ description }}":{{ dirname }}/{{ filename }}