rspec_api_documentation 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,6 @@
1
1
  require 'active_support'
2
+ require 'cgi'
3
+ require 'json'
2
4
 
3
5
  module RspecApiDocumentation
4
6
  extend ActiveSupport::Autoload
@@ -21,6 +23,7 @@ module RspecApiDocumentation
21
23
  autoload :HtmlWriter
22
24
  autoload :JsonWriter
23
25
  autoload :IndexWriter
26
+ autoload :Curl
24
27
 
25
28
  def self.configuration
26
29
  @configuration ||= Configuration.new
@@ -46,6 +46,7 @@ module RspecApiDocumentation
46
46
  add_setting :template_path, :default => File.expand_path("../../../templates", __FILE__)
47
47
  add_setting :filter, :default => :all
48
48
  add_setting :exclusion_filter, :default => nil
49
+ add_setting :url_prefix, :default => ""
49
50
  add_setting :app, :default => lambda { |config|
50
51
  if defined?(Rails)
51
52
  Rails.application
@@ -54,6 +55,8 @@ module RspecApiDocumentation
54
55
  end
55
56
  }
56
57
 
58
+ add_setting :curl_host, :default => nil
59
+
57
60
  def settings
58
61
  @settings ||= {}
59
62
  end
@@ -0,0 +1,52 @@
1
+ require 'active_support/core_ext/object/to_query'
2
+
3
+ module RspecApiDocumentation
4
+ class Curl < Struct.new(:method, :path, :data, :headers)
5
+ attr_accessor :host
6
+
7
+ def output(config_host)
8
+ self.host = config_host
9
+ send(method.downcase)
10
+ end
11
+
12
+ def post
13
+ "curl #{url} #{post_data} -X POST #{headers}"
14
+ end
15
+
16
+ def get
17
+ "curl #{url}#{get_data} -X GET #{headers}"
18
+ end
19
+
20
+ def put
21
+ "curl #{url} #{post_data} -X PUT #{headers}"
22
+ end
23
+
24
+ def delete
25
+ "curl #{url} -X DELETE #{headers}"
26
+ end
27
+
28
+ def url
29
+ "#{host}#{path}"
30
+ end
31
+
32
+ def headers
33
+ super.map do |k, v|
34
+ "-H \"#{format_header(k, v)}\""
35
+ end.join(" ")
36
+ end
37
+
38
+ def get_data
39
+ "?#{data}" unless data.blank?
40
+ end
41
+
42
+ def post_data
43
+ "-d \"#{data}\""
44
+ end
45
+
46
+ private
47
+ def format_header(header, value)
48
+ formatted_header = header.gsub(/^HTTP_/, '').titleize.split.join("-")
49
+ "#{formatted_header}: #{value}"
50
+ end
51
+ end
52
+ end
@@ -1,5 +1,4 @@
1
- require 'rack/test/methods'
2
- require 'rack'
1
+ require 'rack/test'
3
2
  require 'webmock'
4
3
 
5
4
  module RspecApiDocumentation
@@ -83,110 +82,115 @@ module RspecApiDocumentation
83
82
  end
84
83
  end
85
84
 
86
- module InstanceMethods
87
- def client
88
- @client ||= TestClient.new(self)
89
- end
85
+ def client
86
+ @client ||= TestClient.new(self)
87
+ end
90
88
 
91
- def destination
92
- @destination ||= TestServer.new(self)
93
- end
89
+ def destination
90
+ @destination ||= TestServer.new(self)
91
+ end
94
92
 
95
- def callback_url
96
- raise "You must define callback_url"
97
- end
93
+ def callback_url
94
+ raise "You must define callback_url"
95
+ end
98
96
 
99
- def do_request(extra_params = {})
100
- @extra_params = extra_params
101
- params_or_body = nil
102
- path_or_query = path
97
+ def do_request(extra_params = {})
98
+ @extra_params = extra_params
103
99
 
104
- if method == :get && !query_string.blank?
105
- path_or_query = path + "?#{query_string}"
106
- else
107
- params_or_body = respond_to?(:raw_post) ? raw_post : params
108
- end
100
+ params_or_body = nil
101
+ path_or_query = path
109
102
 
110
- client.send(method, path_or_query, params_or_body)
103
+ if method == :get && !query_string.blank?
104
+ path_or_query = path + "?#{query_string}"
105
+ else
106
+ params_or_body = respond_to?(:raw_post) ? raw_post : params
111
107
  end
112
108
 
113
- def query_string
114
- query = params.to_a.map do |param|
115
- param.map! { |a| CGI.escape(a.to_s) }
116
- param.join("=")
117
- end
118
- query.join("&")
119
- end
109
+ client.send(method, path_or_query, params_or_body)
110
+ end
120
111
 
121
- def params
122
- return unless example.metadata[:parameters]
123
- parameters = example.metadata[:parameters].inject({}) do |hash, param|
124
- set_param(hash, param)
125
- end
126
- parameters.merge!(extra_params)
127
- parameters
112
+ def query_string
113
+ query = params.to_a.map do |param|
114
+ param.map! { |a| CGI.escape(a.to_s) }
115
+ param.join("=")
128
116
  end
117
+ query.join("&")
118
+ end
129
119
 
130
- def method
131
- example.metadata[:method]
120
+ def params
121
+ return unless example.metadata[:parameters]
122
+ parameters = example.metadata[:parameters].inject({}) do |hash, param|
123
+ set_param(hash, param)
132
124
  end
125
+ parameters.merge!(extra_params)
126
+ parameters
127
+ end
133
128
 
134
- def in_path?(param)
135
- path_params.include?(param)
136
- end
129
+ def method
130
+ example.metadata[:method]
131
+ end
137
132
 
138
- def path_params
139
- example.metadata[:path].scan(/:(\w+)/).flatten
140
- end
133
+ def in_path?(param)
134
+ path_params.include?(param)
135
+ end
141
136
 
142
- def path
143
- example.metadata[:path].gsub(/:(\w+)/) do |match|
144
- if respond_to?($1)
145
- send($1)
146
- else
147
- match
148
- end
137
+ def path_params
138
+ example.metadata[:path].scan(/:(\w+)/).flatten
139
+ end
140
+
141
+ def path
142
+ example.metadata[:path].gsub(/:(\w+)/) do |match|
143
+ if extra_params.keys.include?($1)
144
+ delete_extra_param($1)
145
+ elsif respond_to?($1)
146
+ send($1)
147
+ else
148
+ match
149
149
  end
150
150
  end
151
+ end
151
152
 
152
- def app
153
- RspecApiDocumentation.configuration.app
154
- end
153
+ def app
154
+ RspecApiDocumentation.configuration.app
155
+ end
155
156
 
156
- def explanation(text)
157
- example.metadata[:explanation] = text
158
- end
157
+ def explanation(text)
158
+ example.metadata[:explanation] = text
159
+ end
159
160
 
160
- def status
161
- last_response.status
162
- end
161
+ def status
162
+ last_response.status
163
+ end
163
164
 
164
- def response_body
165
- last_response.body
166
- end
165
+ def response_body
166
+ last_response.body
167
+ end
167
168
 
168
- private
169
- def extra_params
170
- return {} if @extra_params.nil?
171
- @extra_params.inject({}) do |h, (k, v)|
172
- h[k.to_s] = v
173
- h
174
- end
169
+ private
170
+ def extra_params
171
+ return {} if @extra_params.nil?
172
+ @extra_params.inject({}) do |h, (k, v)|
173
+ h[k.to_s] = v
174
+ h
175
175
  end
176
+ end
176
177
 
177
- def set_param(hash, param)
178
- key = param[:name]
179
- return hash if !respond_to?(key) || in_path?(key)
178
+ def delete_extra_param(key)
179
+ @extra_params.delete(key.to_sym) || @extra_params.delete(key.to_s)
180
+ end
180
181
 
181
- if param[:scope]
182
- hash[param[:scope].to_s] ||= {}
183
- hash[param[:scope].to_s][key] = send(key)
184
- else
185
- hash[key] = send(key)
186
- end
182
+ def set_param(hash, param)
183
+ key = param[:name]
184
+ return hash if !respond_to?(key) || in_path?(key)
187
185
 
188
- hash
186
+ if param[:scope]
187
+ hash[param[:scope].to_s] ||= {}
188
+ hash[param[:scope].to_s][key] = send(key)
189
+ else
190
+ hash[key] = send(key)
189
191
  end
192
+
193
+ hash
190
194
  end
191
195
  end
192
196
  end
@@ -49,6 +49,7 @@ module RspecApiDocumentation
49
49
 
50
50
  def initialize(example, configuration)
51
51
  @example = example
52
+ @host = configuration.curl_host
52
53
  self.template_path = configuration.template_path
53
54
  end
54
55
 
@@ -68,5 +69,20 @@ module RspecApiDocumentation
68
69
  basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '')
69
70
  "#{basename}.html"
70
71
  end
72
+
73
+ def requests
74
+ super.map do |hash|
75
+ if @host
76
+ hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl
77
+ else
78
+ hash[:curl] = nil
79
+ end
80
+ hash
81
+ end
82
+ end
83
+
84
+ def url_prefix
85
+ configuration.url_prefix
86
+ end
71
87
  end
72
88
  end
@@ -15,10 +15,10 @@ module RspecApiDocumentation
15
15
 
16
16
  def write
17
17
  File.open(docs_dir.join("index.json"), "w+") do |f|
18
- f.write JsonIndex.new(index).to_json
18
+ f.write JsonIndex.new(index, configuration).to_json
19
19
  end
20
20
  index.examples.each do |example|
21
- json_example = JsonExample.new(example)
21
+ json_example = JsonExample.new(example, configuration)
22
22
  FileUtils.mkdir_p(docs_dir.join(json_example.dirname))
23
23
  File.open(docs_dir.join(json_example.dirname, json_example.filename), "w+") do |f|
24
24
  f.write json_example.to_json
@@ -28,8 +28,9 @@ module RspecApiDocumentation
28
28
  end
29
29
 
30
30
  class JsonIndex
31
- def initialize(index)
31
+ def initialize(index, configuration)
32
32
  @index = index
33
+ @configuration = configuration
33
34
  end
34
35
 
35
36
  def sections
@@ -37,7 +38,7 @@ module RspecApiDocumentation
37
38
  end
38
39
 
39
40
  def examples
40
- @index.examples.map { |example| JsonExample.new(example) }
41
+ @index.examples.map { |example| JsonExample.new(example, @configuration) }
41
42
  end
42
43
 
43
44
  def to_json
@@ -59,8 +60,9 @@ module RspecApiDocumentation
59
60
  class JsonExample
60
61
  delegate :method, :to => :@example
61
62
 
62
- def initialize(example)
63
+ def initialize(example, configuration)
63
64
  @example = example
65
+ @host = configuration.curl_host
64
66
  end
65
67
 
66
68
  def method_missing(method, *args, &block)
@@ -89,5 +91,16 @@ module RspecApiDocumentation
89
91
  :requests => requests
90
92
  }.to_json
91
93
  end
94
+
95
+ def requests
96
+ super.map do |hash|
97
+ if @host
98
+ hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl
99
+ else
100
+ hash[:curl] = nil
101
+ end
102
+ hash
103
+ end
104
+ end
92
105
  end
93
106
  end
@@ -26,9 +26,10 @@ module RspecApiDocumentation
26
26
  end
27
27
 
28
28
  def last_headers
29
- session.last_request.env.select do |k, v|
29
+ headers = session.last_request.env.select do |k, v|
30
30
  k =~ /^(HTTP_|CONTENT_TYPE)/
31
31
  end
32
+ Hash[headers]
32
33
  end
33
34
 
34
35
  def last_query_string
@@ -80,6 +81,7 @@ module RspecApiDocumentation
80
81
  request_metadata[:response_status_text] = Rack::Utils::HTTP_STATUS_CODES[last_response.status]
81
82
  request_metadata[:response_body] = prettify_json(last_response.body)
82
83
  request_metadata[:response_headers] = format_headers(last_response.headers)
84
+ request_metadata[:curl] = Curl.new(method.to_s, action, request_body, last_headers)
83
85
 
84
86
  metadata[:requests] ||= []
85
87
  metadata[:requests] << request_metadata
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.3.1
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,77 +11,88 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-01-25 00:00:00.000000000Z
14
+ date: 2012-02-03 00:00:00.000000000Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rspec
18
- requirement: &70151618292380 !ruby/object:Gem::Requirement
18
+ requirement: &70173877407600 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
22
22
  - !ruby/object:Gem::Version
23
- version: '0'
23
+ version: 2.6.0
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *70151618292380
26
+ version_requirements: *70173877407600
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activesupport
29
- requirement: &70151618291040 !ruby/object:Gem::Requirement
29
+ requirement: &70173877407120 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ! '>='
33
33
  - !ruby/object:Gem::Version
34
- version: '0'
34
+ version: 3.0.0
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *70151618291040
37
+ version_requirements: *70173877407120
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: i18n
40
- requirement: &70151618289580 !ruby/object:Gem::Requirement
40
+ requirement: &70173877406600 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
- version: '0'
45
+ version: 0.1.0
46
46
  type: :runtime
47
47
  prerelease: false
48
- version_requirements: *70151618289580
48
+ version_requirements: *70173877406600
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: rack-test
51
- requirement: &70151618288780 !ruby/object:Gem::Requirement
51
+ requirement: &70173877406140 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ! '>='
55
55
  - !ruby/object:Gem::Version
56
- version: '0'
56
+ version: 0.5.5
57
57
  type: :runtime
58
58
  prerelease: false
59
- version_requirements: *70151618288780
59
+ version_requirements: *70173877406140
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: mustache
62
- requirement: &70151618287740 !ruby/object:Gem::Requirement
62
+ requirement: &70173877405680 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ! '>='
66
66
  - !ruby/object:Gem::Version
67
- version: '0'
67
+ version: 0.99.0
68
68
  type: :runtime
69
69
  prerelease: false
70
- version_requirements: *70151618287740
70
+ version_requirements: *70173877405680
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: webmock
73
- requirement: &70151618286920 !ruby/object:Gem::Requirement
73
+ requirement: &70173877405220 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
76
  - - ! '>='
77
77
  - !ruby/object:Gem::Version
78
- version: '0'
78
+ version: 1.7.0
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: *70173877405220
82
+ - !ruby/object:Gem::Dependency
83
+ name: json
84
+ requirement: &70173877404740 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: 1.4.0
79
90
  type: :runtime
80
91
  prerelease: false
81
- version_requirements: *70151618286920
92
+ version_requirements: *70173877404740
82
93
  - !ruby/object:Gem::Dependency
83
94
  name: fakefs
84
- requirement: &70151618285800 !ruby/object:Gem::Requirement
95
+ requirement: &70173877404360 !ruby/object:Gem::Requirement
85
96
  none: false
86
97
  requirements:
87
98
  - - ! '>='
@@ -89,10 +100,10 @@ dependencies:
89
100
  version: '0'
90
101
  type: :development
91
102
  prerelease: false
92
- version_requirements: *70151618285800
103
+ version_requirements: *70173877404360
93
104
  - !ruby/object:Gem::Dependency
94
105
  name: sinatra
95
- requirement: &70151618283740 !ruby/object:Gem::Requirement
106
+ requirement: &70173877403900 !ruby/object:Gem::Requirement
96
107
  none: false
97
108
  requirements:
98
109
  - - ! '>='
@@ -100,7 +111,7 @@ dependencies:
100
111
  version: '0'
101
112
  type: :development
102
113
  prerelease: false
103
- version_requirements: *70151618283740
114
+ version_requirements: *70173877403900
104
115
  description: Generate API docs from your test suite
105
116
  email:
106
117
  - chris@smartlogicsolutions.com
@@ -113,6 +124,7 @@ files:
113
124
  - lib/rspec_api_documentation/api_documentation.rb
114
125
  - lib/rspec_api_documentation/api_formatter.rb
115
126
  - lib/rspec_api_documentation/configuration.rb
127
+ - lib/rspec_api_documentation/curl.rb
116
128
  - lib/rspec_api_documentation/dsl.rb
117
129
  - lib/rspec_api_documentation/example.rb
118
130
  - lib/rspec_api_documentation/html_writer.rb