rspec_api_documentation 0.9.2 → 1.0.0
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.
- data/lib/rspec_api_documentation.rb +11 -8
- data/lib/rspec_api_documentation/api_documentation.rb +1 -2
- data/lib/rspec_api_documentation/configuration.rb +0 -2
- data/lib/rspec_api_documentation/curl.rb +1 -1
- data/lib/rspec_api_documentation/example.rb +1 -1
- data/lib/rspec_api_documentation/writers/combined_json_writer.rb +20 -0
- data/lib/rspec_api_documentation/writers/combined_text_writer.rb +106 -0
- data/lib/rspec_api_documentation/writers/formatter.rb +11 -0
- data/lib/rspec_api_documentation/writers/html_writer.rb +102 -0
- data/lib/rspec_api_documentation/writers/index_writer.rb +16 -0
- data/lib/rspec_api_documentation/writers/json_iodocs_writer.rb +111 -0
- data/lib/rspec_api_documentation/writers/json_writer.rb +111 -0
- data/templates/rspec_api_documentation/html_example.mustache +12 -41
- data/templates/rspec_api_documentation/html_index.mustache +9 -2
- metadata +10 -28
- data/lib/rspec_api_documentation/combined_json_writer.rb +0 -18
- data/lib/rspec_api_documentation/combined_text_writer.rb +0 -104
- data/lib/rspec_api_documentation/html_writer.rb +0 -107
- data/lib/rspec_api_documentation/index_writer.rb +0 -14
- data/lib/rspec_api_documentation/json_iodocs_writer.rb +0 -107
- data/lib/rspec_api_documentation/json_writer.rb +0 -111
- data/lib/rspec_api_documentation/wurl_writer.rb +0 -110
- data/templates/assets/img/glyphicons-halflings-white.png +0 -0
- data/templates/assets/img/glyphicons-halflings.png +0 -0
- data/templates/assets/javascripts/application.js +0 -250
- data/templates/assets/javascripts/codemirror.js +0 -3636
- data/templates/assets/javascripts/jquery-1-7-2.js +0 -9401
- data/templates/assets/javascripts/jquery-base64.js +0 -189
- data/templates/assets/javascripts/jquery-livequery.js +0 -226
- data/templates/assets/javascripts/jquery-ui-1-8-16-min.js +0 -791
- data/templates/assets/javascripts/mode/css/css.js +0 -124
- data/templates/assets/javascripts/mode/htmlmixed/htmlmixed.js +0 -85
- data/templates/assets/javascripts/mode/javascript/javascript.js +0 -361
- data/templates/assets/javascripts/mode/xml/xml.js +0 -325
- data/templates/assets/stylesheets/application.css +0 -68
- data/templates/assets/stylesheets/bootstrap.css +0 -4960
- data/templates/assets/stylesheets/codemirror.css +0 -230
- data/templates/rspec_api_documentation/example.json +0 -1
- data/templates/rspec_api_documentation/index.json +0 -1
- data/templates/rspec_api_documentation/wurl_example.mustache +0 -242
- data/templates/rspec_api_documentation/wurl_index.mustache +0 -27
@@ -14,7 +14,6 @@ module RspecApiDocumentation
|
|
14
14
|
autoload :ApiDocumentation
|
15
15
|
autoload :ApiFormatter
|
16
16
|
autoload :Example
|
17
|
-
autoload :ExampleGroup
|
18
17
|
autoload :Index
|
19
18
|
autoload :ClientBase
|
20
19
|
autoload :Headers
|
@@ -24,15 +23,19 @@ module RspecApiDocumentation
|
|
24
23
|
autoload :RackTestClient
|
25
24
|
autoload :OAuth2MACClient, "rspec_api_documentation/oauth2_mac_client"
|
26
25
|
autoload :TestServer
|
27
|
-
autoload :HtmlWriter
|
28
|
-
autoload :WurlWriter
|
29
|
-
autoload :JsonWriter
|
30
|
-
autoload :JsonIodocsWriter
|
31
|
-
autoload :IndexWriter
|
32
|
-
autoload :CombinedTextWriter
|
33
|
-
autoload :CombinedJsonWriter
|
34
26
|
autoload :Curl
|
35
27
|
|
28
|
+
module Writers
|
29
|
+
extend ActiveSupport::Autoload
|
30
|
+
|
31
|
+
autoload :HtmlWriter
|
32
|
+
autoload :JsonWriter
|
33
|
+
autoload :JsonIodocsWriter
|
34
|
+
autoload :IndexWriter
|
35
|
+
autoload :CombinedTextWriter
|
36
|
+
autoload :CombinedJsonWriter
|
37
|
+
end
|
38
|
+
|
36
39
|
def self.configuration
|
37
40
|
@configuration ||= Configuration.new
|
38
41
|
end
|
@@ -14,7 +14,6 @@ module RspecApiDocumentation
|
|
14
14
|
FileUtils.rm_rf(docs_dir, :secure => true)
|
15
15
|
end
|
16
16
|
FileUtils.mkdir_p(docs_dir)
|
17
|
-
FileUtils.cp_r(File.join(configuration.template_path, "assets"), docs_dir)
|
18
17
|
end
|
19
18
|
|
20
19
|
def document_example(rspec_example)
|
@@ -32,7 +31,7 @@ module RspecApiDocumentation
|
|
32
31
|
|
33
32
|
def writers
|
34
33
|
[*configuration.format].map do |format|
|
35
|
-
RspecApiDocumentation.const_get("#{format}_writer".classify)
|
34
|
+
RspecApiDocumentation::Writers.const_get("#{format}_writer".classify)
|
36
35
|
end
|
37
36
|
end
|
38
37
|
end
|
@@ -17,7 +17,6 @@ module RspecApiDocumentation
|
|
17
17
|
subconfig = self.class.new(self)
|
18
18
|
subconfig.filter = name
|
19
19
|
subconfig.docs_dir = self.docs_dir.join(name.to_s)
|
20
|
-
subconfig.url_prefix = "#{self.url_prefix}/#{name}"
|
21
20
|
yield subconfig
|
22
21
|
groups << subconfig
|
23
22
|
end
|
@@ -47,7 +46,6 @@ module RspecApiDocumentation
|
|
47
46
|
add_setting :template_path, :default => File.expand_path("../../../templates", __FILE__)
|
48
47
|
add_setting :filter, :default => :all
|
49
48
|
add_setting :exclusion_filter, :default => nil
|
50
|
-
add_setting :url_prefix, :default => ""
|
51
49
|
add_setting :app, :default => lambda { |config|
|
52
50
|
if defined?(Rails)
|
53
51
|
Rails.application
|
@@ -25,9 +25,9 @@ module RspecApiDocumentation
|
|
25
25
|
|
26
26
|
def should_document?
|
27
27
|
return false if pending? || !metadata[:resource_name] || !metadata[:document]
|
28
|
-
return true if configuration.filter == :all
|
29
28
|
return false if (Array(metadata[:document]) & Array(configuration.exclusion_filter)).length > 0
|
30
29
|
return true if (Array(metadata[:document]) & Array(configuration.filter)).length > 0
|
30
|
+
return true if configuration.filter == :all
|
31
31
|
end
|
32
32
|
|
33
33
|
def public?
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'rspec_api_documentation/writers/json_writer'
|
2
|
+
|
3
|
+
module RspecApiDocumentation
|
4
|
+
module Writers
|
5
|
+
class CombinedJsonWriter
|
6
|
+
def self.write(index, configuration)
|
7
|
+
File.open(configuration.docs_dir.join("combined.json"), "w+") do |f|
|
8
|
+
examples = []
|
9
|
+
index.examples.each do |rspec_example|
|
10
|
+
examples << Formatter.to_json(JsonExample.new(rspec_example, configuration))
|
11
|
+
end
|
12
|
+
|
13
|
+
f.write "["
|
14
|
+
f.write examples.join(",")
|
15
|
+
f.write "]"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module RspecApiDocumentation
|
2
|
+
module Writers
|
3
|
+
class CombinedTextWriter
|
4
|
+
def self.write(index, configuration)
|
5
|
+
index.examples.each do |rspec_example|
|
6
|
+
example = CombinedTextExample.new(rspec_example)
|
7
|
+
FileUtils.mkdir_p(configuration.docs_dir.join(example.resource_name))
|
8
|
+
File.open(configuration.docs_dir.join(example.resource_name, "index.txt"), "a+") do |f|
|
9
|
+
f.print example.description
|
10
|
+
f.print example.parameters
|
11
|
+
|
12
|
+
example.requests.each_with_index do |(request, response), i|
|
13
|
+
f.puts "Request:"
|
14
|
+
f.puts request
|
15
|
+
f.puts
|
16
|
+
f.puts "Response:"
|
17
|
+
f.puts response
|
18
|
+
|
19
|
+
if i + 1 < example.requests.count
|
20
|
+
f.puts
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
unless rspec_example == index.examples.last
|
25
|
+
f.puts
|
26
|
+
f.puts
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.format_hash(hash, separator="=")
|
33
|
+
hash.sort_by { |k, v| k }.inject("") do |out, (k, v)|
|
34
|
+
out << " #{k}#{separator}#{v}\n"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class CombinedTextExample
|
40
|
+
attr_reader :example
|
41
|
+
|
42
|
+
def initialize(example)
|
43
|
+
@example = example
|
44
|
+
end
|
45
|
+
|
46
|
+
def resource_name
|
47
|
+
example.resource_name.downcase.gsub(/\s+/, '_')
|
48
|
+
end
|
49
|
+
|
50
|
+
def description
|
51
|
+
example.description + "\n" + "-" * example.description.length + "\n\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
def parameters
|
55
|
+
return "" unless example.metadata[:parameters]
|
56
|
+
"Parameters:\n" + example.metadata[:parameters].inject("") do |out, parameter|
|
57
|
+
out << " * #{parameter[:name]} - #{parameter[:description]}\n"
|
58
|
+
end + "\n"
|
59
|
+
end
|
60
|
+
|
61
|
+
def requests
|
62
|
+
return [] unless example.metadata[:requests]
|
63
|
+
example.metadata[:requests].map do |request|
|
64
|
+
[format_request(request), format_response(request)]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def format_request(request)
|
70
|
+
[
|
71
|
+
[
|
72
|
+
" #{request[:request_method]} #{request[:request_path]}",
|
73
|
+
format_hash(request[:request_headers], ": ")
|
74
|
+
],
|
75
|
+
[
|
76
|
+
format_string(request[:request_body]) || format_hash(request[:request_query_parameters])
|
77
|
+
]
|
78
|
+
].map { |x| x.compact.join("\n") }.reject(&:blank?).join("\n\n") + "\n"
|
79
|
+
end
|
80
|
+
|
81
|
+
def format_response(request)
|
82
|
+
[
|
83
|
+
[
|
84
|
+
" Status: #{request[:response_status]} #{request[:response_status_text]}",
|
85
|
+
format_hash(request[:response_headers], ": ")
|
86
|
+
],
|
87
|
+
[
|
88
|
+
format_string(request[:response_body])
|
89
|
+
]
|
90
|
+
].map { |x| x.compact.join("\n") }.reject(&:blank?).join("\n\n") + "\n"
|
91
|
+
end
|
92
|
+
|
93
|
+
def format_string(string)
|
94
|
+
return unless string
|
95
|
+
string.split("\n").map { |line| " #{line}" }.join("\n")
|
96
|
+
end
|
97
|
+
|
98
|
+
def format_hash(hash, separator="=")
|
99
|
+
return unless hash
|
100
|
+
hash.sort_by { |k, v| k }.map do |k, v|
|
101
|
+
" #{k}#{separator}#{v}"
|
102
|
+
end.join("\n")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'mustache'
|
2
|
+
|
3
|
+
module RspecApiDocumentation
|
4
|
+
module Writers
|
5
|
+
class HtmlWriter
|
6
|
+
attr_accessor :index, :configuration
|
7
|
+
|
8
|
+
def initialize(index, configuration)
|
9
|
+
self.index = index
|
10
|
+
self.configuration = configuration
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.write(index, configuration)
|
14
|
+
writer = new(index, configuration)
|
15
|
+
writer.write
|
16
|
+
end
|
17
|
+
|
18
|
+
def write
|
19
|
+
File.open(configuration.docs_dir.join("index.html"), "w+") do |f|
|
20
|
+
f.write HtmlIndex.new(index, configuration).render
|
21
|
+
end
|
22
|
+
index.examples.each do |example|
|
23
|
+
html_example = HtmlExample.new(example, configuration)
|
24
|
+
FileUtils.mkdir_p(configuration.docs_dir.join(html_example.dirname))
|
25
|
+
File.open(configuration.docs_dir.join(html_example.dirname, html_example.filename), "w+") do |f|
|
26
|
+
f.write html_example.render
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class HtmlIndex < Mustache
|
33
|
+
def initialize(index, configuration)
|
34
|
+
@index = index
|
35
|
+
@configuration = configuration
|
36
|
+
self.template_path = configuration.template_path
|
37
|
+
self.template_name = "rspec_api_documentation/html_index"
|
38
|
+
end
|
39
|
+
|
40
|
+
def api_name
|
41
|
+
@configuration.api_name
|
42
|
+
end
|
43
|
+
|
44
|
+
def sections
|
45
|
+
IndexWriter.sections(examples, @configuration)
|
46
|
+
end
|
47
|
+
|
48
|
+
def examples
|
49
|
+
@index.examples.map { |example| HtmlExample.new(example, @configuration) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class HtmlExample < Mustache
|
54
|
+
def initialize(example, configuration)
|
55
|
+
@example = example
|
56
|
+
@host = configuration.curl_host
|
57
|
+
self.template_path = configuration.template_path
|
58
|
+
self.template_name = "rspec_api_documentation/html_example"
|
59
|
+
end
|
60
|
+
|
61
|
+
def method_missing(method, *args, &block)
|
62
|
+
@example.send(method, *args, &block)
|
63
|
+
end
|
64
|
+
|
65
|
+
def respond_to?(method, include_private = false)
|
66
|
+
super || @example.respond_to?(method, include_private)
|
67
|
+
end
|
68
|
+
|
69
|
+
def dirname
|
70
|
+
resource_name.downcase.gsub(/\s+/, '_')
|
71
|
+
end
|
72
|
+
|
73
|
+
def filename
|
74
|
+
basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '')
|
75
|
+
basename = Digest::MD5.new.update(description).to_s if basename.blank?
|
76
|
+
"#{basename}.html"
|
77
|
+
end
|
78
|
+
|
79
|
+
def requests
|
80
|
+
super.map do |hash|
|
81
|
+
hash[:request_headers_text] = format_hash(hash[:request_headers])
|
82
|
+
hash[:request_query_parameters_text] = format_hash(hash[:request_query_parameters])
|
83
|
+
hash[:response_headers_text] = format_hash(hash[:response_headers])
|
84
|
+
if @host
|
85
|
+
hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl
|
86
|
+
else
|
87
|
+
hash[:curl] = nil
|
88
|
+
end
|
89
|
+
hash
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def format_hash(hash = {})
|
95
|
+
return nil unless hash.present?
|
96
|
+
hash.collect do |k, v|
|
97
|
+
"#{k}: #{v}"
|
98
|
+
end.join("\n")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "active_support/core_ext/enumerable"
|
2
|
+
|
3
|
+
module RspecApiDocumentation
|
4
|
+
module Writers
|
5
|
+
module IndexWriter
|
6
|
+
def sections(examples, configuration)
|
7
|
+
resources = examples.group_by(&:resource_name).inject([]) do |arr, (resource_name, examples)|
|
8
|
+
ordered_examples = configuration.keep_source_order ? examples : examples.sort_by(&:description)
|
9
|
+
arr.push(:resource_name => resource_name, :examples => ordered_examples)
|
10
|
+
end
|
11
|
+
configuration.keep_source_order ? resources : resources.sort_by { |resource| resource[:resource_name] }
|
12
|
+
end
|
13
|
+
module_function :sections
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'rspec_api_documentation/writers/formatter'
|
2
|
+
|
3
|
+
module RspecApiDocumentation
|
4
|
+
module Writers
|
5
|
+
class JsonIodocsWriter
|
6
|
+
attr_accessor :index, :configuration, :api_key
|
7
|
+
delegate :docs_dir, :to => :configuration
|
8
|
+
|
9
|
+
def initialize(index, configuration)
|
10
|
+
self.index = index
|
11
|
+
self.configuration = configuration
|
12
|
+
self.api_key = configuration.api_name.parameterize
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.write(index, configuration)
|
16
|
+
writer = new(index, configuration)
|
17
|
+
writer.write
|
18
|
+
end
|
19
|
+
|
20
|
+
def write
|
21
|
+
File.open(docs_dir.join("apiconfig.json"), "w+") do |file|
|
22
|
+
file.write Formatter.to_json(ApiConfig.new(configuration))
|
23
|
+
end
|
24
|
+
File.open(docs_dir.join("#{api_key}.json"), "w+") do |file|
|
25
|
+
file.write Formatter.to_json(JsonIndex.new(index, configuration))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class JsonIndex
|
31
|
+
def initialize(index, configuration)
|
32
|
+
@index = index
|
33
|
+
@configuration = configuration
|
34
|
+
end
|
35
|
+
|
36
|
+
def sections
|
37
|
+
IndexWriter.sections(examples, @configuration)
|
38
|
+
end
|
39
|
+
|
40
|
+
def examples
|
41
|
+
@index.examples.map { |example| JsonExample.new(example, @configuration) }
|
42
|
+
end
|
43
|
+
|
44
|
+
def as_json(opts = nil)
|
45
|
+
sections.inject({:endpoints => []}) do |h, section|
|
46
|
+
h[:endpoints].push(
|
47
|
+
:name => section[:resource_name],
|
48
|
+
:methods => section[:examples].map do |example|
|
49
|
+
example.as_json(opts)
|
50
|
+
end
|
51
|
+
)
|
52
|
+
h
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class JsonExample
|
58
|
+
def initialize(example, configuration)
|
59
|
+
@example = example
|
60
|
+
end
|
61
|
+
|
62
|
+
def method_missing(method, *args, &block)
|
63
|
+
@example.send(method, *args, &block)
|
64
|
+
end
|
65
|
+
|
66
|
+
def parameters
|
67
|
+
params = []
|
68
|
+
if @example.respond_to?(:parameters)
|
69
|
+
@example.parameters.map do |param|
|
70
|
+
params << {
|
71
|
+
"Name" => param[:name],
|
72
|
+
"Description" => param[:description],
|
73
|
+
"Default" => "",
|
74
|
+
"Required" => param[:required] ? "Y" : "N"
|
75
|
+
}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
params
|
79
|
+
end
|
80
|
+
|
81
|
+
def as_json(opts = nil)
|
82
|
+
{
|
83
|
+
:MethodName => description,
|
84
|
+
:Synopsis => explanation,
|
85
|
+
:HTTPMethod => http_method,
|
86
|
+
:URI => (requests.first[:request_path] rescue ""),
|
87
|
+
:RequiresOAuth => "N",
|
88
|
+
:parameters => parameters
|
89
|
+
}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class ApiConfig
|
94
|
+
def initialize(configuration)
|
95
|
+
@configuration = configuration
|
96
|
+
@api_key = configuration.api_name.parameterize
|
97
|
+
end
|
98
|
+
|
99
|
+
def as_json(opts = nil)
|
100
|
+
{
|
101
|
+
@api_key.to_sym => {
|
102
|
+
:name => @configuration.api_name,
|
103
|
+
:protocol => "http",
|
104
|
+
:publicPath => "",
|
105
|
+
:baseURL => @configuration.curl_host
|
106
|
+
}
|
107
|
+
}
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|