rspec_api_documentation 0.9.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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