rspec_api_documentation 0.4.4 → 0.5.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.
@@ -0,0 +1,79 @@
1
+ module RspecApiDocumentation
2
+ class ClientBase < Struct.new(:context, :options)
3
+ include Headers
4
+ include Syntax
5
+
6
+ delegate :example, :app, :to => :context
7
+ delegate :metadata, :to => :example
8
+
9
+ def get(*args)
10
+ process :get, *args
11
+ end
12
+
13
+ def post(*args)
14
+ process :post, *args
15
+ end
16
+
17
+ def put(*args)
18
+ process :put, *args
19
+ end
20
+
21
+ def delete(*args)
22
+ process :delete, *args
23
+ end
24
+
25
+ private
26
+
27
+ def process(method, path, params = {})
28
+ do_request(method, path, params)
29
+ document_example(method.to_s.upcase, path, params)
30
+ end
31
+
32
+ def document_example(method, path, params)
33
+ return unless metadata[:document]
34
+
35
+ input = last_request.env["rack.input"]
36
+ input.rewind
37
+ request_body = input.read
38
+
39
+ request_metadata = {}
40
+
41
+ request_metadata[:request_method] = method
42
+ request_metadata[:request_path] = path
43
+ request_metadata[:request_body] = highlight_syntax(request_body, content_type, true)
44
+ request_metadata[:request_headers] = format_headers(request_headers)
45
+ request_metadata[:request_query_parameters] = format_query_hash(query_hash)
46
+ request_metadata[:response_status] = status
47
+ request_metadata[:response_status_text] = Rack::Utils::HTTP_STATUS_CODES[status]
48
+ request_metadata[:response_body] = highlight_syntax(response_body, response_headers['Content-Type'])
49
+ request_metadata[:response_headers] = format_headers(response_headers)
50
+ request_metadata[:curl] = Curl.new(method, path, request_body, request_headers)
51
+
52
+ metadata[:requests] ||= []
53
+ metadata[:requests] << request_metadata
54
+ end
55
+
56
+ def query_hash
57
+ strings = query_string.split("&")
58
+ arrays = strings.map do |segment|
59
+ segment.split("=")
60
+ end
61
+ Hash[arrays]
62
+ end
63
+
64
+ def format_query_hash(query_hash)
65
+ return if query_hash.blank?
66
+ query_hash.map do |key, value|
67
+ "#{key}: #{CGI.unescape(value)}"
68
+ end.join("\n")
69
+ end
70
+
71
+ def headers(method, path, params)
72
+ if options && options[:headers]
73
+ options[:headers]
74
+ else
75
+ {}
76
+ end
77
+ end
78
+ end
79
+ end
@@ -56,6 +56,7 @@ module RspecApiDocumentation
56
56
  }
57
57
 
58
58
  add_setting :curl_host, :default => nil
59
+ add_setting :keep_source_order, :default => false
59
60
 
60
61
  def settings
61
62
  @settings ||= {}
@@ -6,12 +6,15 @@ module RspecApiDocumentation
6
6
  module DSL
7
7
  extend ActiveSupport::Concern
8
8
 
9
+ delegate :response_headers, :status, :response_body, :to => :client
10
+ delegate :request_method, :request_headers, :request_body, :to => :destination
11
+
9
12
  module ClassMethods
10
13
  def self.define_action(method)
11
14
  define_method method do |*args, &block|
12
15
  options = if args.last.is_a?(Hash) then args.pop else {} end
13
16
  options[:method] = method
14
- options[:path] = args.first
17
+ options[:route] = args.first
15
18
  args.push(options)
16
19
  args[0] = "#{method.to_s.upcase} #{args[0]}"
17
20
  context(*args, &block)
@@ -89,7 +92,7 @@ module RspecApiDocumentation
89
92
  end
90
93
 
91
94
  def client
92
- @client ||= TestClient.new(self)
95
+ @client ||= RackTestClient.new(self)
93
96
  end
94
97
 
95
98
  def destination
@@ -150,11 +153,11 @@ module RspecApiDocumentation
150
153
  end
151
154
 
152
155
  def path_params
153
- example.metadata[:path].scan(/:(\w+)/).flatten
156
+ example.metadata[:route].scan(/:(\w+)/).flatten
154
157
  end
155
158
 
156
159
  def path
157
- example.metadata[:path].gsub(/:(\w+)/) do |match|
160
+ example.metadata[:route].gsub(/:(\w+)/) do |match|
158
161
  if extra_params.keys.include?($1)
159
162
  delete_extra_param($1)
160
163
  elsif respond_to?($1)
@@ -173,14 +176,6 @@ module RspecApiDocumentation
173
176
  example.metadata[:explanation] = text
174
177
  end
175
178
 
176
- def status
177
- client.last_response.status
178
- end
179
-
180
- def response_body
181
- client.last_response.body
182
- end
183
-
184
179
  private
185
180
  def extra_params
186
181
  return {} if @extra_params.nil?
@@ -220,5 +215,4 @@ def self.resource(*args, &block)
220
215
  end
221
216
 
222
217
  RSpec.configuration.include RspecApiDocumentation::DSL, :api_docs_dsl => true
223
- RSpec.configuration.include Rack::Test::Methods, :api_docs_dsl => true
224
218
  RSpec.configuration.backtrace_clean_patterns << %r{lib/rspec_api_documentation/dsl\.rb}
@@ -20,7 +20,7 @@ module RspecApiDocumentation
20
20
  end
21
21
 
22
22
  def http_method
23
- metadata[:method]
23
+ metadata[:method].to_s.upcase
24
24
  end
25
25
 
26
26
  def should_document?
@@ -0,0 +1,23 @@
1
+ module RspecApiDocumentation
2
+ module Headers
3
+ private
4
+
5
+ def env_to_headers(env)
6
+ headers = {}
7
+ env.each do |key, value|
8
+ # HTTP_ACCEPT_CHARSET => Accept-Charset
9
+ if key =~ /^(HTTP_|CONTENT_TYPE)/
10
+ header = key.gsub(/^HTTP_/, '').titleize.split.join("-")
11
+ headers[header] = value
12
+ end
13
+ end
14
+ headers
15
+ end
16
+
17
+ def format_headers(headers)
18
+ headers.map do |key, value|
19
+ "#{key}: #{value}"
20
+ end.join("\n")
21
+ end
22
+ end
23
+ end
@@ -36,7 +36,7 @@ module RspecApiDocumentation
36
36
  end
37
37
 
38
38
  def sections
39
- IndexWriter.sections(examples)
39
+ IndexWriter.sections(examples, @configuration)
40
40
  end
41
41
 
42
42
  def examples
@@ -1,10 +1,13 @@
1
+ require "active_support/core_ext/enumerable"
2
+
1
3
  module RspecApiDocumentation
2
4
  module IndexWriter
3
- def sections(examples)
5
+ def sections(examples, configuration)
4
6
  resources = examples.group_by(&:resource_name).inject([]) do |arr, (resource_name, examples)|
5
- arr << { :resource_name => resource_name, :examples => examples.sort_by(&:description) }
7
+ ordered_examples = configuration.keep_source_order ? examples : examples.sort_by(&:description)
8
+ arr.push(:resource_name => resource_name, :examples => ordered_examples)
6
9
  end
7
- resources.sort_by { |resource| resource[:resource_name] }
10
+ configuration.keep_source_order ? resources : resources.sort_by { |resource| resource[:resource_name] }
8
11
  end
9
12
  module_function :sections
10
13
  end
@@ -34,7 +34,7 @@ module RspecApiDocumentation
34
34
  end
35
35
 
36
36
  def sections
37
- IndexWriter.sections(examples)
37
+ IndexWriter.sections(examples, @configuration)
38
38
  end
39
39
 
40
40
  def examples
@@ -0,0 +1,52 @@
1
+ module RspecApiDocumentation
2
+ class OAuth2MACClient < ClientBase
3
+ include WebMock::API
4
+ attr_accessor :last_response, :last_request
5
+ private :last_response, :last_request
6
+
7
+ def request_headers
8
+ env_to_headers(last_request.env)
9
+ end
10
+
11
+ def response_headers
12
+ last_response.headers
13
+ end
14
+
15
+ def query_string
16
+ last_request.env["QUERY_STRING"]
17
+ end
18
+
19
+ def status
20
+ last_response.status
21
+ end
22
+
23
+ def response_body
24
+ last_response.body
25
+ end
26
+
27
+ def content_type
28
+ last_request.content_type
29
+ end
30
+
31
+ protected
32
+
33
+ def do_request(method, path, params)
34
+ self.last_response = access_token.send(method, "http://example.com#{path}", :body => params, :header => headers(method, path, params))
35
+ end
36
+
37
+ class ProxyApp < Struct.new(:client, :app)
38
+ def call(env)
39
+ client.last_request = Struct.new(:env, :content_type).new(env, env["CONTENT_TYPE"])
40
+ app.call(env.merge("SCRIPT_NAME" => ""))
41
+ end
42
+ end
43
+
44
+ def access_token
45
+ @access_token ||= begin
46
+ app = ProxyApp.new(self, context.app)
47
+ stub_request(:any, %r{http://example\.com}).to_rack(app)
48
+ Rack::OAuth2::Client.new(options.merge(:host => "example.com", :scheme => "http")).access_token!
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,51 @@
1
+ require "coderay"
2
+
3
+ module RspecApiDocumentation
4
+ class RackTestClient < ClientBase
5
+
6
+ delegate :last_request, :last_response, :to => :rack_test_session
7
+ private :last_request, :last_response
8
+
9
+ def request_headers
10
+ env_to_headers(last_request.env)
11
+ end
12
+
13
+ def response_headers
14
+ last_response.headers
15
+ end
16
+
17
+ def query_string
18
+ last_request.env["QUERY_STRING"]
19
+ end
20
+
21
+ def status
22
+ last_response.status
23
+ end
24
+
25
+ def response_body
26
+ last_response.body
27
+ end
28
+
29
+ def content_type
30
+ last_request.content_type
31
+ end
32
+
33
+ protected
34
+
35
+ def do_request(method, path, params)
36
+ rack_test_session.send(method, path, params, headers(method, path, params))
37
+ end
38
+
39
+ private
40
+
41
+ def rack_test_session
42
+ @rack_test_session ||= Struct.new(:app) do
43
+ begin
44
+ include Rack::Test::Methods
45
+ rescue LoadError
46
+ raise "#{self.class.name} requires Rack::Test >= 0.5.5. Please add it to your test dependencies."
47
+ end
48
+ end.new(app)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,33 @@
1
+ require "coderay"
2
+
3
+ module RspecApiDocumentation
4
+ module Syntax
5
+ private
6
+
7
+ def highlight_syntax(body, content_type, is_query_string = false)
8
+ return if body.blank?
9
+ begin
10
+ case content_type
11
+ when /json/
12
+ CodeRay.scan(JSON.pretty_generate(JSON.parse(body)), :json).div
13
+ when /html/
14
+ CodeRay.scan(body, :html).div
15
+ when /javascript/
16
+ CodeRay.scan(body, :java_script).div
17
+ when /xml/
18
+ CodeRay.scan(body, :xml).div
19
+ else
20
+ body = prettify_request_body(body) if is_query_string
21
+ "<pre>#{body}</pre>"
22
+ end
23
+ rescue Exception => e
24
+ "<pre>#{e.inspect}</pre>"
25
+ end
26
+ end
27
+
28
+ def prettify_request_body(string)
29
+ return if string.blank?
30
+ CGI.unescape(string.split("&").join("\n"))
31
+ end
32
+ end
33
+ end
@@ -1,44 +1,32 @@
1
1
  module RspecApiDocumentation
2
- class TestServer < Struct.new(:session)
3
- delegate :example, :last_request, :last_response, :to => :session
2
+ class TestServer < Struct.new(:context)
3
+ include Headers
4
+ include Syntax
5
+
6
+ delegate :example, :to => :context
4
7
  delegate :metadata, :to => :example
5
8
 
9
+ attr_reader :request_method, :request_headers, :request_body
10
+
6
11
  def call(env)
7
- env["rack.input"].rewind
12
+ input = env["rack.input"]
13
+ input.rewind
14
+
15
+ @request_method = env["REQUEST_METHOD"]
16
+ @request_headers = env_to_headers(env)
17
+ @request_body = input.read
8
18
 
9
19
  request_metadata = {}
10
20
 
11
- request_metadata[:method] = env["REQUEST_METHOD"]
12
- request_metadata[:route] = env["PATH_INFO"]
13
- request_metadata[:request_body] = prettify_json(env["rack.input"].read)
14
- request_metadata[:request_headers] = headers(env)
21
+ request_metadata[:request_method] = request_method
22
+ request_metadata[:request_path] = env["PATH_INFO"]
23
+ request_metadata[:request_body] = highlight_syntax(request_body, request_headers["Content-Type"], true)
24
+ request_metadata[:request_headers] = format_headers(@request_headers)
15
25
 
16
26
  metadata[:requests] ||= []
17
27
  metadata[:requests] << request_metadata
18
28
 
19
29
  return [200, {}, [""]]
20
30
  end
21
-
22
- private
23
-
24
- def headers(env)
25
- env.
26
- select do |k, v|
27
- k =~ /^(HTTP_|CONTENT_TYPE)/
28
- end.
29
- map do |key, value|
30
- # HTTP_ACCEPT_CHARSET => Accept-Charset
31
- formatted_key = key.gsub(/^HTTP_/, '').titleize.split.join("-")
32
- "#{formatted_key}: #{value}"
33
- end.join("\n")
34
- end
35
-
36
- def prettify_json(json)
37
- begin
38
- JSON.pretty_generate(JSON.parse(json))
39
- rescue
40
- nil
41
- end
42
- end
43
31
  end
44
32
  end
@@ -1,4 +1,5 @@
1
1
  require 'active_support'
2
+ require 'active_support/inflector'
2
3
  require 'cgi'
3
4
  require 'json'
4
5
 
@@ -15,10 +16,14 @@ module RspecApiDocumentation
15
16
  autoload :Example
16
17
  autoload :ExampleGroup
17
18
  autoload :Index
18
- autoload :TestClient
19
+ autoload :ClientBase
20
+ autoload :Headers
21
+ autoload :Syntax
19
22
  end
20
23
 
21
24
  autoload :DSL
25
+ autoload :RackTestClient
26
+ autoload :OAuth2MACClient, "rspec_api_documentation/oauth2_mac_client"
22
27
  autoload :TestServer
23
28
  autoload :HtmlWriter
24
29
  autoload :JsonWriter
@@ -22,6 +22,7 @@
22
22
 
23
23
  <div class="article">
24
24
  <h2>{{ description }}</h2>
25
+ <h3>{{ http_method }} {{ route }}</h3>
25
26
  {{# explanation }}
26
27
  <p class="explanation">
27
28
  {{ explanation }}
@@ -57,18 +58,18 @@
57
58
  <h4>Headers</h4>
58
59
  <pre class="request headers">{{ request_headers }}</pre>
59
60
  <h4>Route</h4>
60
- <pre class="request route highlight">{{ http_method }} {{ route }}</pre>
61
+ <pre class="request route highlight">{{ request_method }} {{ request_path }}</pre>
61
62
  {{# request_query_parameters }}
62
63
  <h4>Query Parameters</h4>
63
64
  <pre class="request query_parameters highlight">{{ request_query_parameters }}</pre>
64
65
  {{/ request_query_parameters }}
65
66
  {{# request_body }}
66
67
  <h4>Body</h4>
67
- <pre class="request highlight">{{ request_body }}</pre>
68
+ <div class="request body">{{{ request_body }}}</div>
68
69
  {{/ request_body }}
69
70
 
70
71
  {{# curl }}
71
- <h4>Curl</h4>
72
+ <h4>cURL</h4>
72
73
  <pre class="request">{{ curl }}</pre>
73
74
  {{/ curl }}
74
75
 
@@ -80,7 +81,7 @@
80
81
  <pre class="response status">{{ response_status }} {{ response_status_text}}</pre>
81
82
  {{# response_body }}
82
83
  <h4>Body</h4>
83
- <pre class="response body highlight">{{ response_body }}</pre>
84
+ <div class="response body">{{{ response_body }}}</div>
84
85
  {{/ response_body }}
85
86
  {{/ response_status }}
86
87
  {{/ requests }}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec_api_documentation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-04-03 00:00:00.000000000Z
14
+ date: 2012-04-24 00:00:00.000000000Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rspec
18
- requirement: &70121277388400 !ruby/object:Gem::Requirement
18
+ requirement: &70224876720480 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: 2.6.0
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *70121277388400
26
+ version_requirements: *70224876720480
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
- requirement: &70121277387560 !ruby/object:Gem::Requirement
29
+ requirement: &70224876719900 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ! '>='
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: 3.0.0
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *70121277387560
37
+ version_requirements: *70224876719900
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: i18n
40
- requirement: &70121277386040 !ruby/object:Gem::Requirement
40
+ requirement: &70224876719320 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
@@ -45,54 +45,54 @@ dependencies:
45
45
  version: 0.1.0
46
46
  type: :runtime
47
47
  prerelease: false
48
- version_requirements: *70121277386040
48
+ version_requirements: *70224876719320
49
49
  - !ruby/object:Gem::Dependency
50
- name: rack-test
51
- requirement: &70121277384380 !ruby/object:Gem::Requirement
50
+ name: mustache
51
+ requirement: &70224876718740 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ! '>='
55
55
  - !ruby/object:Gem::Version
56
- version: 0.5.5
56
+ version: 0.99.0
57
57
  type: :runtime
58
58
  prerelease: false
59
- version_requirements: *70121277384380
59
+ version_requirements: *70224876718740
60
60
  - !ruby/object:Gem::Dependency
61
- name: mustache
62
- requirement: &70121277383220 !ruby/object:Gem::Requirement
61
+ name: webmock
62
+ requirement: &70224876718160 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ! '>='
66
66
  - !ruby/object:Gem::Version
67
- version: 0.99.0
67
+ version: 1.7.0
68
68
  type: :runtime
69
69
  prerelease: false
70
- version_requirements: *70121277383220
70
+ version_requirements: *70224876718160
71
71
  - !ruby/object:Gem::Dependency
72
- name: webmock
73
- requirement: &70121277382640 !ruby/object:Gem::Requirement
72
+ name: json
73
+ requirement: &70224876717600 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
76
  - - ! '>='
77
77
  - !ruby/object:Gem::Version
78
- version: 1.7.0
78
+ version: 1.4.0
79
79
  type: :runtime
80
80
  prerelease: false
81
- version_requirements: *70121277382640
81
+ version_requirements: *70224876717600
82
82
  - !ruby/object:Gem::Dependency
83
- name: json
84
- requirement: &70121277370000 !ruby/object:Gem::Requirement
83
+ name: coderay
84
+ requirement: &70224876715300 !ruby/object:Gem::Requirement
85
85
  none: false
86
86
  requirements:
87
87
  - - ! '>='
88
88
  - !ruby/object:Gem::Version
89
- version: 1.4.0
89
+ version: 1.0.7.rc1
90
90
  type: :runtime
91
91
  prerelease: false
92
- version_requirements: *70121277370000
92
+ version_requirements: *70224876715300
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: fakefs
95
- requirement: &70121277369620 !ruby/object:Gem::Requirement
95
+ requirement: &70224876714800 !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements:
98
98
  - - ! '>='
@@ -100,10 +100,10 @@ dependencies:
100
100
  version: '0'
101
101
  type: :development
102
102
  prerelease: false
103
- version_requirements: *70121277369620
103
+ version_requirements: *70224876714800
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: sinatra
106
- requirement: &70121277369140 !ruby/object:Gem::Requirement
106
+ requirement: &70224876714220 !ruby/object:Gem::Requirement
107
107
  none: false
108
108
  requirements:
109
109
  - - ! '>='
@@ -111,10 +111,10 @@ dependencies:
111
111
  version: '0'
112
112
  type: :development
113
113
  prerelease: false
114
- version_requirements: *70121277369140
114
+ version_requirements: *70224876714220
115
115
  - !ruby/object:Gem::Dependency
116
- name: builder
117
- requirement: &70121277368700 !ruby/object:Gem::Requirement
116
+ name: aruba
117
+ requirement: &70224876713680 !ruby/object:Gem::Requirement
118
118
  none: false
119
119
  requirements:
120
120
  - - ! '>='
@@ -122,10 +122,10 @@ dependencies:
122
122
  version: '0'
123
123
  type: :development
124
124
  prerelease: false
125
- version_requirements: *70121277368700
125
+ version_requirements: *70224876713680
126
126
  - !ruby/object:Gem::Dependency
127
- name: aruba
128
- requirement: &70121277368240 !ruby/object:Gem::Requirement
127
+ name: capybara
128
+ requirement: &70224876713140 !ruby/object:Gem::Requirement
129
129
  none: false
130
130
  requirements:
131
131
  - - ! '>='
@@ -133,10 +133,10 @@ dependencies:
133
133
  version: '0'
134
134
  type: :development
135
135
  prerelease: false
136
- version_requirements: *70121277368240
136
+ version_requirements: *70224876713140
137
137
  - !ruby/object:Gem::Dependency
138
- name: capybara
139
- requirement: &70121277367700 !ruby/object:Gem::Requirement
138
+ name: rake
139
+ requirement: &70224876712660 !ruby/object:Gem::Requirement
140
140
  none: false
141
141
  requirements:
142
142
  - - ! '>='
@@ -144,10 +144,10 @@ dependencies:
144
144
  version: '0'
145
145
  type: :development
146
146
  prerelease: false
147
- version_requirements: *70121277367700
147
+ version_requirements: *70224876712660
148
148
  - !ruby/object:Gem::Dependency
149
- name: rake
150
- requirement: &70121277367180 !ruby/object:Gem::Requirement
149
+ name: rack-oauth2
150
+ requirement: &70224876712240 !ruby/object:Gem::Requirement
151
151
  none: false
152
152
  requirements:
153
153
  - - ! '>='
@@ -155,7 +155,7 @@ dependencies:
155
155
  version: '0'
156
156
  type: :development
157
157
  prerelease: false
158
- version_requirements: *70121277367180
158
+ version_requirements: *70224876712240
159
159
  description: Generate API docs from your test suite
160
160
  email:
161
161
  - chris@smartlogicsolutions.com
@@ -167,16 +167,20 @@ extra_rdoc_files: []
167
167
  files:
168
168
  - lib/rspec_api_documentation/api_documentation.rb
169
169
  - lib/rspec_api_documentation/api_formatter.rb
170
+ - lib/rspec_api_documentation/client_base.rb
170
171
  - lib/rspec_api_documentation/configuration.rb
171
172
  - lib/rspec_api_documentation/curl.rb
172
173
  - lib/rspec_api_documentation/dsl.rb
173
174
  - lib/rspec_api_documentation/example.rb
175
+ - lib/rspec_api_documentation/headers.rb
174
176
  - lib/rspec_api_documentation/html_writer.rb
175
177
  - lib/rspec_api_documentation/index.rb
176
178
  - lib/rspec_api_documentation/index_writer.rb
177
179
  - lib/rspec_api_documentation/json_writer.rb
180
+ - lib/rspec_api_documentation/oauth2_mac_client.rb
181
+ - lib/rspec_api_documentation/rack_test_client.rb
178
182
  - lib/rspec_api_documentation/railtie.rb
179
- - lib/rspec_api_documentation/test_client.rb
183
+ - lib/rspec_api_documentation/syntax.rb
180
184
  - lib/rspec_api_documentation/test_server.rb
181
185
  - lib/rspec_api_documentation.rb
182
186
  - lib/tasks/docs.rake
@@ -1,130 +0,0 @@
1
- module RspecApiDocumentation
2
- class TestClient < Struct.new(:session, :options)
3
- attr_accessor :user
4
-
5
- delegate :example, :last_response, :last_request, :to => :session
6
- delegate :metadata, :to => :example
7
-
8
- def get(*args)
9
- process :get, *args
10
- end
11
-
12
- def post(*args)
13
- process :post, *args
14
- end
15
-
16
- def put(*args)
17
- process :put, *args
18
- end
19
-
20
- def delete(*args)
21
- process :delete, *args
22
- end
23
-
24
- def sign_in(user)
25
- @user = user
26
- end
27
-
28
- def last_headers
29
- headers = last_request.env.select do |k, v|
30
- k =~ /^(HTTP_|CONTENT_TYPE)/
31
- end
32
- Hash[headers]
33
- end
34
-
35
- def last_query_string
36
- last_request.env["QUERY_STRING"]
37
- end
38
-
39
- def last_query_hash
40
- strings = last_query_string.split("&")
41
- arrays = strings.map do |segment|
42
- segment.split("=")
43
- end
44
- Hash[arrays]
45
- end
46
-
47
- def headers(method, action, params)
48
- if options && options[:headers]
49
- options[:headers]
50
- else
51
- {}
52
- end
53
- end
54
-
55
- private
56
- def process(method, action, params = {})
57
- session.send(method, action, params, headers(method, action, params))
58
-
59
- document_example(method, action, params)
60
- end
61
-
62
- def document_example(method, action, params)
63
- return unless metadata[:document]
64
-
65
- input = last_request.env["rack.input"]
66
- input.rewind
67
- request_body = input.read
68
-
69
- request_metadata = {}
70
-
71
- request_metadata[:method] = method.to_s.upcase
72
- request_metadata[:route] = action
73
- if is_json?(request_body)
74
- request_metadata[:request_body] = prettify_json(request_body)
75
- else
76
- request_metadata[:request_body] = prettify_request_body(request_body)
77
- end
78
- request_metadata[:request_headers] = format_headers(last_headers)
79
- request_metadata[:request_query_parameters] = format_query_hash(last_query_hash)
80
- request_metadata[:response_status] = last_response.status
81
- request_metadata[:response_status_text] = Rack::Utils::HTTP_STATUS_CODES[last_response.status]
82
- if is_json?(request_body)
83
- request_metadata[:response_body] = prettify_json(last_response.body)
84
- else
85
- request_metadata[:response_body] = last_response.body
86
- end
87
- request_metadata[:response_headers] = format_headers(last_response.headers)
88
- request_metadata[:curl] = Curl.new(method.to_s, action, request_body, last_headers)
89
-
90
- metadata[:requests] ||= []
91
- metadata[:requests] << request_metadata
92
- end
93
-
94
- def format_headers(headers)
95
- headers.map do |key, value|
96
- # HTTP_ACCEPT_CHARSET => Accept-Charset
97
- formatted_key = key.gsub(/^HTTP_/, '').titleize.split.join("-")
98
- "#{formatted_key}: #{value}"
99
- end.join("\n")
100
- end
101
-
102
- def format_query_hash(query_hash)
103
- return if query_hash.blank?
104
- query_hash.map do |key, value|
105
- "#{key}: #{CGI.unescape(value)}"
106
- end.join("\n")
107
- end
108
-
109
- def prettify_json(json)
110
- begin
111
- JSON.pretty_generate(JSON.parse(json))
112
- rescue
113
- nil
114
- end
115
- end
116
-
117
- def prettify_request_body(string)
118
- return if string.blank?
119
- CGI.unescape(string.split("&").join("\n"))
120
- end
121
-
122
- def is_json?(string)
123
- begin
124
- JSON.parse(string)
125
- rescue
126
- false
127
- end
128
- end
129
- end
130
- end