Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
Expand Up @@ -7,3 +7,4 @@ example/public/docs
*.gem
*.swp
/html/
.idea
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ RspecApiDocumentation.configure do |config|
# An array of output format(s).
# Possible values are :json, :html, :combined_text, :combined_json,
# :json_iodocs, :textile, :markdown, :append_json, :slate,
# :api_blueprint
# :api_blueprint, :postman
config.format = [:html]

# Location of templates
Expand Down Expand Up @@ -172,6 +172,7 @@ end
* **markdown**: Generates an index file and example files in Markdown.
* **api_blueprint**: Generates an index file and example files in [APIBlueprint](https://apiblueprint.org).
* **append_json**: Lets you selectively run specs without destroying current documentation. See section below.
* **postman**: (In Alpha) Generates a Postman collection JSON file that you can import

### append_json

Expand Down
162 changes: 162 additions & 0 deletions features/postman.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
Feature: Postman

Background:
Given a file named "app.rb" with:
"""
class App
def self.call(env)
request = Rack::Request.new(env)
response = Rack::Response.new
response["Content-Type"] = "text/plain"
response.write("Hello, #{request.params["target"]}!")
response.finish
end
end
"""
And a file named "app_spec.rb" with:
"""
require "rspec_api_documentation"
require "rspec_api_documentation/dsl"

RspecApiDocumentation.configure do |config|
config.app = App
config.api_name = "app"
config.api_explanation = "desc"
config.format = :postman
config.io_docs_protocol = "https"
end

resource "Greetings" do
explanation "Greetings API methods"
header "Content-Type", "application/json"

get "/greetings" do
parameter :target, "The thing you want to greet"
parameter :type, "foo"

example "Greeting your favorite gem" do
do_request({:target => "rspec_api_documentation", :type => "foo"})

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"

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
"""
When I run `rspec app_spec.rb --require ./app.rb --format RspecApiDocumentation::ApiFormatter`

Scenario: Output helpful progress to the console
Then the output should contain:
"""
Generating API Docs
Greetings
GET /greetings
* Greeting your favorite gem
* Greeting your favorite developers of your favorite gem
"""
And the output should contain "2 examples, 0 failures"
And the exit status should be 0

Scenario: File should look like we expect
Then the file "doc/api/app.postman_collection.json" should contain JSON exactly like:
"""
{
"info": {
"name": "app",
"description": "desc",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Greetings",
"description": "Greetings API methods",
"item": [
{
"name": "Greeting your favorite developers of your favorite gem",
"request": {
"method": "GET",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {},
"url": {
"host": [
"{{application_url}}"
],
"path": [
"greetings"
],
"query" : [
{
"key": "target",
"value": "",
"equals": true,
"description": "The thing you want to greet",
"disabled": true
}
],
"variable": []
},
"description": "\n * `target`: The thing you want to greet\n * `type`: foo"
},
"response": []
},
{
"name": "Greeting your favorite gem",
"request": {
"method": "GET",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {},
"url": {
"host": [
"{{application_url}}"
],
"path": [
"greetings"
],
"query" : [
{
"key": "target",
"value": "",
"equals": true,
"description": "The thing you want to greet",
"disabled": true
},
{
"key": "type",
"value": "",
"equals": true,
"description": "foo",
"disabled": true
}
],
"variable": []
},
"description": "\n * `target`: The thing you want to greet\n * `type`: foo"
},
"response": []
}
]
}
]
}
"""


4 changes: 4 additions & 0 deletions lib/rspec_api_documentation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ module Writers
autoload :CombinedJsonWriter
autoload :SlateWriter
autoload :ApiBlueprintWriter
autoload :PostmanWriter
end

module Views
Expand All @@ -62,6 +63,9 @@ module Views
autoload :SlateExample
autoload :ApiBlueprintIndex
autoload :ApiBlueprintExample
autoload :PostmanIndex
autoload :PostmanRequestExample
autoload :PostmanRequestMetadata
end

def self.configuration
Expand Down
42 changes: 42 additions & 0 deletions lib/rspec_api_documentation/views/postman_index.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module RspecApiDocumentation
module Views
class PostmanIndex
POSTMAN_SCHEMA = 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json'.freeze

def initialize(index, configuration)
@index = index
@configuration = configuration
end

def sections
Writers::IndexHelper.sections(examples, @configuration)
end

def examples
@index.examples.map do |example|
Views::PostmanRequestExample.new(example)
end
end

def as_json(opts = nil)
collections = { info: { name: @configuration.api_name,
description: @configuration.api_explanation,
schema: POSTMAN_SCHEMA },
item: []
}

sections.each do |section|
folder = { name: section[:resource_name],
description: section[:resource_explanation],
item: section[:examples].map do |example|
example.as_json(opts)
end
}
collections[:item] << folder
end

collections
end
end
end
end
35 changes: 35 additions & 0 deletions lib/rspec_api_documentation/views/postman_request_example.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module RspecApiDocumentation
module Views
class PostmanRequestExample
attr_reader :example, :metadata

def initialize(example)
@example = example
@metadata = Views::PostmanRequestMetadata.new(example)
end

def method_missing(method, *args, &block)
example.send(method, *args, &block)
end

def as_json(options = nil)
{
name: description,
request: {
method: http_method,
header: [metadata.content_type],
body: metadata.body,
url: {
host: ['{{application_url}}'],
path: metadata.tokenized_path,
query: metadata.query_in_url,
variable: metadata.variables_for_url
},
description: metadata.request_description
},
response: []
}
end
end
end
end
Loading