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.
Files changed (41) hide show
  1. data/lib/rspec_api_documentation.rb +11 -8
  2. data/lib/rspec_api_documentation/api_documentation.rb +1 -2
  3. data/lib/rspec_api_documentation/configuration.rb +0 -2
  4. data/lib/rspec_api_documentation/curl.rb +1 -1
  5. data/lib/rspec_api_documentation/example.rb +1 -1
  6. data/lib/rspec_api_documentation/writers/combined_json_writer.rb +20 -0
  7. data/lib/rspec_api_documentation/writers/combined_text_writer.rb +106 -0
  8. data/lib/rspec_api_documentation/writers/formatter.rb +11 -0
  9. data/lib/rspec_api_documentation/writers/html_writer.rb +102 -0
  10. data/lib/rspec_api_documentation/writers/index_writer.rb +16 -0
  11. data/lib/rspec_api_documentation/writers/json_iodocs_writer.rb +111 -0
  12. data/lib/rspec_api_documentation/writers/json_writer.rb +111 -0
  13. data/templates/rspec_api_documentation/html_example.mustache +12 -41
  14. data/templates/rspec_api_documentation/html_index.mustache +9 -2
  15. metadata +10 -28
  16. data/lib/rspec_api_documentation/combined_json_writer.rb +0 -18
  17. data/lib/rspec_api_documentation/combined_text_writer.rb +0 -104
  18. data/lib/rspec_api_documentation/html_writer.rb +0 -107
  19. data/lib/rspec_api_documentation/index_writer.rb +0 -14
  20. data/lib/rspec_api_documentation/json_iodocs_writer.rb +0 -107
  21. data/lib/rspec_api_documentation/json_writer.rb +0 -111
  22. data/lib/rspec_api_documentation/wurl_writer.rb +0 -110
  23. data/templates/assets/img/glyphicons-halflings-white.png +0 -0
  24. data/templates/assets/img/glyphicons-halflings.png +0 -0
  25. data/templates/assets/javascripts/application.js +0 -250
  26. data/templates/assets/javascripts/codemirror.js +0 -3636
  27. data/templates/assets/javascripts/jquery-1-7-2.js +0 -9401
  28. data/templates/assets/javascripts/jquery-base64.js +0 -189
  29. data/templates/assets/javascripts/jquery-livequery.js +0 -226
  30. data/templates/assets/javascripts/jquery-ui-1-8-16-min.js +0 -791
  31. data/templates/assets/javascripts/mode/css/css.js +0 -124
  32. data/templates/assets/javascripts/mode/htmlmixed/htmlmixed.js +0 -85
  33. data/templates/assets/javascripts/mode/javascript/javascript.js +0 -361
  34. data/templates/assets/javascripts/mode/xml/xml.js +0 -325
  35. data/templates/assets/stylesheets/application.css +0 -68
  36. data/templates/assets/stylesheets/bootstrap.css +0 -4960
  37. data/templates/assets/stylesheets/codemirror.css +0 -230
  38. data/templates/rspec_api_documentation/example.json +0 -1
  39. data/templates/rspec_api_documentation/index.json +0 -1
  40. data/templates/rspec_api_documentation/wurl_example.mustache +0 -242
  41. 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
@@ -39,7 +39,7 @@ module RspecApiDocumentation
39
39
 
40
40
  def headers
41
41
  super.map do |k, v|
42
- "-H \"#{format_header(k, v)}\""
42
+ "\\\n\t-H \"#{format_header(k, v)}\""
43
43
  end.join(" ")
44
44
  end
45
45
 
@@ -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,11 @@
1
+ module RspecApiDocumentation
2
+ module Writers
3
+ module Formatter
4
+
5
+ def self.to_json(object)
6
+ JSON.pretty_generate(object.as_json)
7
+ end
8
+
9
+ end
10
+ end
11
+ 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