rspec-api-documentation 1.1.1.alpha

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