rspec-api-documentation 1.1.1.alpha

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 (39) hide show
  1. checksums.yaml +7 -0
  2. data/lib/rspec_api_documentation.rb +63 -0
  3. data/lib/rspec_api_documentation/api_documentation.rb +38 -0
  4. data/lib/rspec_api_documentation/api_formatter.rb +45 -0
  5. data/lib/rspec_api_documentation/client_base.rb +82 -0
  6. data/lib/rspec_api_documentation/configuration.rb +84 -0
  7. data/lib/rspec_api_documentation/curl.rb +61 -0
  8. data/lib/rspec_api_documentation/dsl.rb +17 -0
  9. data/lib/rspec_api_documentation/dsl/callback.rb +25 -0
  10. data/lib/rspec_api_documentation/dsl/endpoint.rb +134 -0
  11. data/lib/rspec_api_documentation/dsl/resource.rb +83 -0
  12. data/lib/rspec_api_documentation/example.rb +49 -0
  13. data/lib/rspec_api_documentation/headers.rb +32 -0
  14. data/lib/rspec_api_documentation/index.rb +7 -0
  15. data/lib/rspec_api_documentation/oauth2_mac_client.rb +70 -0
  16. data/lib/rspec_api_documentation/rack_test_client.rb +58 -0
  17. data/lib/rspec_api_documentation/railtie.rb +7 -0
  18. data/lib/rspec_api_documentation/test_server.rb +31 -0
  19. data/lib/rspec_api_documentation/views/html_example.rb +16 -0
  20. data/lib/rspec_api_documentation/views/html_index.rb +14 -0
  21. data/lib/rspec_api_documentation/views/markup_example.rb +58 -0
  22. data/lib/rspec_api_documentation/views/markup_index.rb +21 -0
  23. data/lib/rspec_api_documentation/views/textile_example.rb +16 -0
  24. data/lib/rspec_api_documentation/views/textile_index.rb +14 -0
  25. data/lib/rspec_api_documentation/writers/combined_json_writer.rb +20 -0
  26. data/lib/rspec_api_documentation/writers/combined_text_writer.rb +106 -0
  27. data/lib/rspec_api_documentation/writers/formatter.rb +11 -0
  28. data/lib/rspec_api_documentation/writers/general_markup_writer.rb +42 -0
  29. data/lib/rspec_api_documentation/writers/html_writer.rb +21 -0
  30. data/lib/rspec_api_documentation/writers/index_writer.rb +16 -0
  31. data/lib/rspec_api_documentation/writers/json_iodocs_writer.rb +111 -0
  32. data/lib/rspec_api_documentation/writers/json_writer.rb +111 -0
  33. data/lib/rspec_api_documentation/writers/textile_writer.rb +21 -0
  34. data/lib/tasks/docs.rake +7 -0
  35. data/templates/rspec_api_documentation/html_example.mustache +106 -0
  36. data/templates/rspec_api_documentation/html_index.mustache +34 -0
  37. data/templates/rspec_api_documentation/textile_example.mustache +68 -0
  38. data/templates/rspec_api_documentation/textile_index.mustache +10 -0
  39. metadata +267 -0
@@ -0,0 +1,16 @@
1
+ module RspecApiDocumentation
2
+ module Views
3
+ class TextileExample < MarkupExample
4
+ EXTENSION = 'textile'
5
+
6
+ def initialize(example, configuration)
7
+ super
8
+ self.template_name = "rspec_api_documentation/textile_example"
9
+ end
10
+
11
+ def extension
12
+ EXTENSION
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module RspecApiDocumentation
2
+ module Views
3
+ class TextileIndex < MarkupIndex
4
+ def initialize(index, configuration)
5
+ super
6
+ self.template_name = "rspec_api_documentation/textile_index"
7
+ end
8
+
9
+ def examples
10
+ @index.examples.map { |example| TextileExample.new(example, @configuration) }
11
+ end
12
+ end
13
+ end
14
+ end
@@ -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,42 @@
1
+ module RspecApiDocumentation
2
+ module Writers
3
+ class GeneralMarkupWriter
4
+ attr_accessor :index, :configuration
5
+
6
+ INDEX_FILE_NAME = 'index'
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_file_name + '.' + extension), "w+") do |f|
20
+ f.write markup_index_class.new(index, configuration).render
21
+ end
22
+
23
+ index.examples.each do |example|
24
+ markup_example = markup_example_class.new(example, configuration)
25
+ FileUtils.mkdir_p(configuration.docs_dir.join(markup_example.dirname))
26
+
27
+ File.open(configuration.docs_dir.join(markup_example.dirname, markup_example.filename), "w+") do |f|
28
+ f.write markup_example.render
29
+ end
30
+ end
31
+ end
32
+
33
+ def index_file_name
34
+ INDEX_FILE_NAME
35
+ end
36
+
37
+ def extension
38
+ raise 'Parent class. This method should not be called.'
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,21 @@
1
+ module RspecApiDocumentation
2
+ module Writers
3
+ class HtmlWriter < GeneralMarkupWriter
4
+ attr_accessor :index, :configuration
5
+
6
+ EXTENSION = 'html'
7
+
8
+ def markup_index_class
9
+ RspecApiDocumentation::Views::HtmlIndex
10
+ end
11
+
12
+ def markup_example_class
13
+ RspecApiDocumentation::Views::HtmlExample
14
+ end
15
+
16
+ def extension
17
+ EXTENSION
18
+ end
19
+ end
20
+ end
21
+ 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 => @configuration.io_docs_protocol,
104
+ :publicPath => "",
105
+ :baseURL => @configuration.curl_host
106
+ }
107
+ }
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,111 @@
1
+ require 'rspec_api_documentation/writers/formatter'
2
+
3
+ module RspecApiDocumentation
4
+ module Writers
5
+ class JsonWriter
6
+ attr_accessor :index, :configuration
7
+ delegate :docs_dir, :to => :configuration
8
+
9
+ def initialize(index, configuration)
10
+ self.index = index
11
+ self.configuration = configuration
12
+ end
13
+
14
+ def self.write(index, configuration)
15
+ writer = new(index, configuration)
16
+ writer.write
17
+ end
18
+
19
+ def write
20
+ File.open(docs_dir.join("index.json"), "w+") do |f|
21
+ f.write Formatter.to_json(JsonIndex.new(index, configuration))
22
+ end
23
+ index.examples.each do |example|
24
+ json_example = JsonExample.new(example, configuration)
25
+ FileUtils.mkdir_p(docs_dir.join(json_example.dirname))
26
+ File.open(docs_dir.join(json_example.dirname, json_example.filename), "w+") do |f|
27
+ f.write Formatter.to_json(json_example)
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ class JsonIndex
34
+ def initialize(index, configuration)
35
+ @index = index
36
+ @configuration = configuration
37
+ end
38
+
39
+ def sections
40
+ IndexWriter.sections(examples, @configuration)
41
+ end
42
+
43
+ def examples
44
+ @index.examples.map { |example| JsonExample.new(example, @configuration) }
45
+ end
46
+
47
+ def as_json(opts = nil)
48
+ sections.inject({:resources => []}) do |h, section|
49
+ h[:resources].push(
50
+ :name => section[:resource_name],
51
+ :examples => section[:examples].map { |example|
52
+ {
53
+ :description => example.description,
54
+ :link => "#{example.dirname}/#{example.filename}",
55
+ :groups => example.metadata[:document]
56
+ }
57
+ }
58
+ )
59
+ h
60
+ end
61
+ end
62
+ end
63
+
64
+ class JsonExample
65
+ def initialize(example, configuration)
66
+ @example = example
67
+ @host = configuration.curl_host
68
+ end
69
+
70
+ def method_missing(method, *args, &block)
71
+ @example.send(method, *args, &block)
72
+ end
73
+
74
+ def respond_to?(method, include_private = false)
75
+ super || @example.respond_to?(method, include_private)
76
+ end
77
+
78
+ def dirname
79
+ resource_name.downcase.gsub(/\s+/, '_')
80
+ end
81
+
82
+ def filename
83
+ basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '')
84
+ "#{basename}.json"
85
+ end
86
+
87
+ def as_json(opts = nil)
88
+ {
89
+ :resource => resource_name,
90
+ :http_method => http_method,
91
+ :route => route,
92
+ :description => description,
93
+ :explanation => explanation,
94
+ :parameters => respond_to?(:parameters) ? parameters : [],
95
+ :requests => requests
96
+ }
97
+ end
98
+
99
+ def requests
100
+ super.map do |hash|
101
+ if @host
102
+ hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl
103
+ else
104
+ hash[:curl] = nil
105
+ end
106
+ hash
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end