From 25b301e9d5297fbb8e1b1cf8326c29b4f0350936 Mon Sep 17 00:00:00 2001 From: Martin Skinner Date: Fri, 26 Feb 2016 09:41:47 +0100 Subject: [PATCH 1/2] =?UTF-8?q?Merged=20jramos=E2=80=99s=20fork=20back=20i?= =?UTF-8?q?nto=20current=20master?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + features/combined_json.feature | 16 ++++++++----- features/combined_text.feature | 13 +++++----- features/curl.feature | 2 +- features/headers.feature | 2 +- features/html_documentation.feature | 6 ++--- features/json_iodocs.feature | 12 +++++----- features/markdown_documentation.feature | 23 ++++++++++-------- features/oauth2_mac_client.feature | 18 +++++++------- features/patch.feature | 2 +- features/readme.md | 4 ++-- features/redefining_client.feature | 2 +- features/textile_documentation.feature | 24 +++++++++++-------- features/upload_file.feature | 8 +++---- lib/rspec_api_documentation/dsl/resource.rb | 4 ++++ lib/rspec_api_documentation/example.rb | 4 ++++ .../writers/index_helper.rb | 2 +- .../writers/json_writer.rb | 2 ++ spec/dsl_spec.rb | 3 +++ spec/example_spec.rb | 11 +++++++++ spec/writers/index_helper_spec.rb | 8 +++---- .../html_example.mustache | 4 ++++ .../html_index.mustache | 4 ++++ .../markdown_example.mustache | 4 ++++ .../markdown_index.mustache | 4 ++++ .../textile_example.mustache | 4 ++++ .../textile_index.mustache | 4 ++++ 27 files changed, 125 insertions(+), 66 deletions(-) diff --git a/.gitignore b/.gitignore index ded8b1f8..a0190963 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ tmp .rvmrc .ruby-version +.ruby-gemset example/docs example/public/docs *.gem diff --git a/features/combined_json.feature b/features/combined_json.feature index 9a944ffe..55c791b8 100644 --- a/features/combined_json.feature +++ b/features/combined_json.feature @@ -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", diff --git a/features/combined_text.feature b/features/combined_text.feature index ed20ac63..7556fe07 100644 --- a/features/combined_text.feature +++ b/features/combined_text.feature @@ -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! - """ diff --git a/features/curl.feature b/features/curl.feature index 13ac336e..711f8d3a 100644 --- a/features/curl.feature +++ b/features/curl.feature @@ -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 diff --git a/features/headers.feature b/features/headers.feature index d2eba9d8..bd00e043 100644 --- a/features/headers.feature +++ b/features/headers.feature @@ -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 diff --git a/features/html_documentation.feature b/features/html_documentation.feature index 4fb03417..18aa191a 100644 --- a/features/html_documentation.feature +++ b/features/html_documentation.feature @@ -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 diff --git a/features/json_iodocs.feature b/features/json_iodocs.feature index ab1eca8c..319855db 100644 --- a/features/json_iodocs.feature +++ b/features/json_iodocs.feature @@ -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 diff --git a/features/markdown_documentation.feature b/features/markdown_documentation.feature index 268b1234..dcaf48aa 100644 --- a/features/markdown_documentation.feature +++ b/features/markdown_documentation.feature @@ -59,8 +59,8 @@ 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 @@ -68,8 +68,8 @@ Feature: Generate Markdown documentation from test examples 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,7 +95,7 @@ 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 @@ -103,16 +103,18 @@ Feature: Generate Markdown documentation from test examples 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 } ] } - """ Scenario: Example 'Creating an order' file should look like we expect diff --git a/features/oauth2_mac_client.feature b/features/oauth2_mac_client.feature index e528a109..133cf603 100644 --- a/features/oauth2_mac_client.feature +++ b/features/oauth2_mac_client.feature @@ -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 diff --git a/features/patch.feature b/features/patch.feature index bc1390a0..cf815657 100644 --- a/features/patch.feature +++ b/features/patch.feature @@ -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 diff --git a/features/readme.md b/features/readme.md index 1beb68dd..5e8f4c05 100644 --- a/features/readme.md +++ b/features/readme.md @@ -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 diff --git a/features/redefining_client.feature b/features/redefining_client.feature index aff21599..69cde27a 100644 --- a/features/redefining_client.feature +++ b/features/redefining_client.feature @@ -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 diff --git a/features/textile_documentation.feature b/features/textile_documentation.feature index 2d182ff9..0cbaa03d 100644 --- a/features/textile_documentation.feature +++ b/features/textile_documentation.feature @@ -59,8 +59,8 @@ 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 @@ -68,8 +68,8 @@ Feature: Generate Textile documentation from test examples 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,7 +95,7 @@ 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 @@ -103,16 +103,18 @@ Feature: Generate Textile documentation from test examples 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 diff --git a/features/upload_file.feature b/features/upload_file.feature index cf0c942b..b0ea9999 100644 --- a/features/upload_file.feature +++ b/features/upload_file.feature @@ -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 diff --git a/lib/rspec_api_documentation/dsl/resource.rb b/lib/rspec_api_documentation/dsl/resource.rb index 4da33e53..c6854717 100644 --- a/lib/rspec_api_documentation/dsl/resource.rb +++ b/lib/rspec_api_documentation/dsl/resource.rb @@ -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) diff --git a/lib/rspec_api_documentation/example.rb b/lib/rspec_api_documentation/example.rb index 73264b43..73822d45 100644 --- a/lib/rspec_api_documentation/example.rb +++ b/lib/rspec_api_documentation/example.rb @@ -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 diff --git a/lib/rspec_api_documentation/writers/index_helper.rb b/lib/rspec_api_documentation/writers/index_helper.rb index b52b26b4..d030f02e 100644 --- a/lib/rspec_api_documentation/writers/index_helper.rb +++ b/lib/rspec_api_documentation/writers/index_helper.rb @@ -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 diff --git a/lib/rspec_api_documentation/writers/json_writer.rb b/lib/rspec_api_documentation/writers/json_writer.rb index 730426ea..022240ad 100644 --- a/lib/rspec_api_documentation/writers/json_writer.rb +++ b/lib/rspec_api_documentation/writers/json_writer.rb @@ -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, diff --git a/spec/dsl_spec.rb b/spec/dsl_spec.rb index 4fc44237..a9ab1162 100644 --- a/spec/dsl_spec.rb +++ b/spec/dsl_spec.rb @@ -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 diff --git a/spec/example_spec.rb b/spec/example_spec.rb index cef44e93..aa003436 100644 --- a/spec/example_spec.rb +++ b/spec/example_spec.rb @@ -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" diff --git a/spec/writers/index_helper_spec.rb b/spec/writers/index_helper_spec.rb index 2b39c929..b8477db4 100644 --- a/spec/writers/index_helper_spec.rb +++ b/spec/writers/index_helper_spec.rb @@ -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 } diff --git a/templates/rspec_api_documentation/html_example.mustache b/templates/rspec_api_documentation/html_example.mustache index 5e8385c3..518a730e 100644 --- a/templates/rspec_api_documentation/html_example.mustache +++ b/templates/rspec_api_documentation/html_example.mustache @@ -10,6 +10,10 @@

{{resource_name}} API

+ {{# resource_explanation }} + +

{{{ resource_explanation }}}

+ {{/ resource_explanation }}

{{ description }}

diff --git a/templates/rspec_api_documentation/html_index.mustache b/templates/rspec_api_documentation/html_index.mustache index 3df2c6aa..76a338f5 100644 --- a/templates/rspec_api_documentation/html_index.mustache +++ b/templates/rspec_api_documentation/html_index.mustache @@ -14,6 +14,10 @@ {{# sections }}

{{ resource_name }}

+ {{# resource_explanation }} + +

{{{ resource_explanation }}}

+ {{/ resource_explanation }}
    {{# examples }} diff --git a/templates/rspec_api_documentation/markdown_example.mustache b/templates/rspec_api_documentation/markdown_example.mustache index 1183f707..eb6b7713 100644 --- a/templates/rspec_api_documentation/markdown_example.mustache +++ b/templates/rspec_api_documentation/markdown_example.mustache @@ -1,4 +1,8 @@ # {{ resource_name }} API +{{# resource_explanation }} + +{{{ resource_explanation }}} +{{/ resource_explanation }} ## {{ description }} diff --git a/templates/rspec_api_documentation/markdown_index.mustache b/templates/rspec_api_documentation/markdown_index.mustache index bdd11f55..ecfbfd42 100644 --- a/templates/rspec_api_documentation/markdown_index.mustache +++ b/templates/rspec_api_documentation/markdown_index.mustache @@ -2,6 +2,10 @@ {{# sections }} ## {{ resource_name }} +{{# resource_explanation }} + +{{{ resource_explanation }}} +{{/ resource_explanation }} {{# examples }} * [{{ description }}]({{ dirname }}/{{ filename }}) diff --git a/templates/rspec_api_documentation/textile_example.mustache b/templates/rspec_api_documentation/textile_example.mustache index e32917ba..a7e022b4 100644 --- a/templates/rspec_api_documentation/textile_example.mustache +++ b/templates/rspec_api_documentation/textile_example.mustache @@ -1,4 +1,8 @@ h1. {{ resource_name }} API +{{# resource_explanation }} + +{{{ resource_explanation }}} +{{/ resource_explanation }} h2. {{ description }} diff --git a/templates/rspec_api_documentation/textile_index.mustache b/templates/rspec_api_documentation/textile_index.mustache index cbb93d57..02150e66 100644 --- a/templates/rspec_api_documentation/textile_index.mustache +++ b/templates/rspec_api_documentation/textile_index.mustache @@ -2,6 +2,10 @@ h1. {{ api_name }} {{# sections }} h2. {{ resource_name }} +{{# resource_explanation }} + +{{{ resource_explanation }}} +{{/ resource_explanation }} {{# examples }} * "{{ description }}":{{ dirname }}/{{ filename }} From 7a5384823e1e726773fd1747408163a962b1af58 Mon Sep 17 00:00:00 2001 From: Martin Skinner Date: Fri, 26 Feb 2016 15:35:19 +0100 Subject: [PATCH 2/2] updated README - resource sections can have an explanation --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index f6e14440..ccffaf3d 100644 --- a/README.md +++ b/README.md @@ -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.