rspec_api_documentation 0.9.2 → 1.0.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.
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
@@ -1,14 +0,0 @@
1
- require "active_support/core_ext/enumerable"
2
-
3
- module RspecApiDocumentation
4
- module IndexWriter
5
- def sections(examples, configuration)
6
- resources = examples.group_by(&:resource_name).inject([]) do |arr, (resource_name, examples)|
7
- ordered_examples = configuration.keep_source_order ? examples : examples.sort_by(&:description)
8
- arr.push(:resource_name => resource_name, :examples => ordered_examples)
9
- end
10
- configuration.keep_source_order ? resources : resources.sort_by { |resource| resource[:resource_name] }
11
- end
12
- module_function :sections
13
- end
14
- end
@@ -1,107 +0,0 @@
1
- module RspecApiDocumentation
2
- class JsonIodocsWriter
3
- attr_accessor :index, :configuration, :api_key
4
- delegate :docs_dir, :to => :configuration
5
-
6
- def initialize(index, configuration)
7
- self.index = index
8
- self.configuration = configuration
9
- self.api_key = configuration.api_name.parameterize
10
- end
11
-
12
- def self.write(index, configuration)
13
- writer = new(index, configuration)
14
- writer.write
15
- end
16
-
17
- def write
18
- File.open(docs_dir.join("apiconfig.json"), "w+") do |file|
19
- file.write ApiConfig.new(configuration).to_json
20
- end
21
- File.open(docs_dir.join("#{api_key}.json"), "w+") do |file|
22
- file.write JsonIndex.new(index, configuration).to_json
23
- end
24
- end
25
- end
26
-
27
- class JsonIndex
28
- def initialize(index, configuration)
29
- @index = index
30
- @configuration = configuration
31
- end
32
-
33
- def sections
34
- IndexWriter.sections(examples, @configuration)
35
- end
36
-
37
- def examples
38
- @index.examples.map { |example| JsonExample.new(example, @configuration) }
39
- end
40
-
41
- def to_json
42
- sections.inject({:endpoints => []}) do |h, section|
43
- h[:endpoints].push(
44
- :name => section[:resource_name],
45
- :methods => section[:examples].map do |example|
46
- example.to_json
47
- end
48
- )
49
- h
50
- end.to_json
51
- end
52
- end
53
-
54
- class JsonExample
55
- def initialize(example, configuration)
56
- @example = example
57
- end
58
-
59
- def method_missing(method, *args, &block)
60
- @example.send(method, *args, &block)
61
- end
62
-
63
- def parameters
64
- params = []
65
- if @example.respond_to?(:parameters)
66
- @example.parameters.map do |param|
67
- params << {
68
- "Name" => param[:name],
69
- "Description" => param[:description],
70
- "Default" => "",
71
- "Required" => param[:required] ? "Y" : "N"
72
- }
73
- end
74
- end
75
- params
76
- end
77
-
78
- def to_json
79
- {
80
- :MethodName => description,
81
- :Synopsis => explanation,
82
- :HTTPMethod => http_method,
83
- :URI => (requests.first[:request_path] rescue ""),
84
- :RequiresOAuth => "N",
85
- :parameters => parameters
86
- }
87
- end
88
- end
89
-
90
- class ApiConfig
91
- def initialize(configuration)
92
- @configuration = configuration
93
- @api_key = configuration.api_name.parameterize
94
- end
95
-
96
- def to_json
97
- {
98
- @api_key.to_sym => {
99
- :name => @configuration.api_name,
100
- :protocol => "http",
101
- :publicPath => "",
102
- :baseURL => @configuration.curl_host
103
- }
104
- }.to_json
105
- end
106
- end
107
- end
@@ -1,111 +0,0 @@
1
- module RspecApiDocumentation
2
- class JsonWriter
3
- attr_accessor :index, :configuration
4
- delegate :docs_dir, :to => :configuration
5
-
6
- def initialize(index, configuration)
7
- self.index = index
8
- self.configuration = configuration
9
- end
10
-
11
- def self.write(index, configuration)
12
- writer = new(index, configuration)
13
- writer.write
14
- end
15
-
16
- def write
17
- File.open(docs_dir.join("index.json"), "w+") do |f|
18
- f.write JsonIndex.new(index, configuration).to_json
19
- end
20
- index.examples.each do |example|
21
- json_example = JsonExample.new(example, configuration)
22
- FileUtils.mkdir_p(docs_dir.join(json_example.dirname))
23
- File.open(docs_dir.join(json_example.dirname, json_example.filename), "w+") do |f|
24
- f.write json_example.to_json
25
- end
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 to_json
45
- sections.inject({:resources => []}) do |h, section|
46
- h[:resources].push(
47
- :name => section[:resource_name],
48
- :examples => section[:examples].map { |example|
49
- {
50
- :description => example.description,
51
- :link => "#{example.dirname}/#{example.filename}",
52
- :groups => example.metadata[:document]
53
- }
54
- }
55
- )
56
- h
57
- end.to_json
58
- end
59
- end
60
-
61
- class JsonExample
62
- def initialize(example, configuration)
63
- @example = example
64
- @host = configuration.curl_host
65
- end
66
-
67
- def method_missing(method, *args, &block)
68
- @example.send(method, *args, &block)
69
- end
70
-
71
- def respond_to?(method, include_private = false)
72
- super || @example.respond_to?(method, include_private)
73
- end
74
-
75
- def dirname
76
- resource_name.downcase.gsub(/\s+/, '_')
77
- end
78
-
79
- def filename
80
- basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '')
81
- "#{basename}.json"
82
- end
83
-
84
- def as_json
85
- {
86
- :resource => resource_name,
87
- :http_method => http_method,
88
- :route => route,
89
- :description => description,
90
- :explanation => explanation,
91
- :parameters => respond_to?(:parameters) ? parameters : [],
92
- :requests => requests
93
- }
94
- end
95
-
96
- def to_json
97
- as_json.to_json
98
- end
99
-
100
- def requests
101
- super.map do |hash|
102
- if @host
103
- hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl
104
- else
105
- hash[:curl] = nil
106
- end
107
- hash
108
- end
109
- end
110
- end
111
- end
@@ -1,110 +0,0 @@
1
- require 'mustache'
2
-
3
- module RspecApiDocumentation
4
- class WurlWriter
5
- attr_accessor :index, :configuration
6
-
7
- def initialize(index, configuration)
8
- warn "[DEPRECATED] Wurl output is going to be gone in the next release."
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 WurlIndex.new(index, configuration).render
21
- end
22
- index.examples.each do |example|
23
- html_example = WurlExample.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 WurlIndex < Mustache
33
- def initialize(index, configuration)
34
- @index = index
35
- @configuration = configuration
36
- self.template_path = configuration.template_path
37
- end
38
-
39
- def api_name
40
- @configuration.api_name
41
- end
42
-
43
- def sections
44
- IndexWriter.sections(examples, @configuration)
45
- end
46
-
47
- def url_prefix
48
- @configuration.url_prefix
49
- end
50
-
51
- def examples
52
- @index.examples.map { |example| WurlExample.new(example, @configuration) }
53
- end
54
- end
55
-
56
- class WurlExample < Mustache
57
- def initialize(example, configuration)
58
- @example = example
59
- @host = configuration.curl_host
60
- self.template_path = configuration.template_path
61
- end
62
-
63
- def method_missing(method, *args, &block)
64
- @example.send(method, *args, &block)
65
- end
66
-
67
- def respond_to?(method, include_private = false)
68
- super || @example.respond_to?(method, include_private)
69
- end
70
-
71
- def dirname
72
- resource_name.downcase.gsub(/\s+/, '_')
73
- end
74
-
75
- def filename
76
- basename = description.downcase.gsub(/\s+/, '_').gsub(/[^a-z_]/, '')
77
- "#{basename}.html"
78
- end
79
-
80
- def requests
81
- super.collect do |hash|
82
- hash[:request_headers_hash] = hash[:request_headers].collect { |k, v| {:name => k, :value => v} }
83
- hash[:request_headers_text] = format_hash(hash[:request_headers])
84
- hash[:request_path_no_query] = hash[:request_path].split('?').first
85
- hash[:request_query_parameters_text] = format_hash(hash[:request_query_parameters])
86
- hash[:request_query_parameters_hash] = hash[:request_query_parameters].collect { |k, v| {:name => k, :value => v} } if hash[:request_query_parameters].present?
87
- hash[:response_headers_text] = format_hash(hash[:response_headers])
88
- hash[:response_status] = hash[:response_status].to_s + " " + Rack::Utils::HTTP_STATUS_CODES[hash[:response_status]].to_s
89
- if @host
90
- hash[:curl] = hash[:curl].output(@host) if hash[:curl].is_a? RspecApiDocumentation::Curl
91
- else
92
- hash[:curl] = nil
93
- end
94
- hash
95
- end
96
- end
97
-
98
- def url_prefix
99
- configuration.url_prefix
100
- end
101
-
102
- private
103
- def format_hash(hash = {})
104
- return nil unless hash.present?
105
- hash.collect do |k, v|
106
- "#{k}: #{v}"
107
- end.join("\n")
108
- end
109
- end
110
- end
@@ -1,250 +0,0 @@
1
- var headers = ["Accept",
2
- "Accept-Charset",
3
- "Accept-Encoding",
4
- "Accept-Language",
5
- "Authorization",
6
- "Cache-Control",
7
- "Connection",
8
- "Cookie",
9
- "Content-Length",
10
- "Content-MD5",
11
- "Content-Type",
12
- "Date",
13
- "Expect",
14
- "From",
15
- "Host",
16
- "If-Match",
17
- "If-Modified-Since",
18
- "If-None-Match",
19
- "If-Range",
20
- "If-Unmodified-Since",
21
- "Max-Forwards",
22
- "Pragma",
23
- "Proxy-Authorization",
24
- "Range",
25
- "Referer",
26
- "TE",
27
- "Upgrade",
28
- "User-Agent",
29
- "Via",
30
- "Warning"];
31
-
32
- function mirror(textarea, contentType, options) {
33
- $textarea = $(textarea);
34
- if ($textarea.val() != '') {
35
- if(contentType.indexOf('json') >= 0) {
36
- $textarea.val(JSON.stringify(JSON.parse($textarea.val()), undefined, 2));
37
- options.json = true;
38
- options.mode = 'javascript';
39
- } else if (contentType.indexOf('javascript') >= 0) {
40
- options.mode = 'javascript';
41
- } else if (contentType.indexOf('xml') >= 0) {
42
- options.mode = 'xml';
43
- } else {
44
- options.mode = 'htmlmixed';
45
- }
46
- }
47
- return CodeMirror.fromTextArea(textarea, options);
48
- };
49
-
50
- function Wurl(wurlForm) {
51
- this.$wurlForm = $(wurlForm);
52
- var self = this;
53
-
54
- this.requestBodyMirror = mirror(this.$wurlForm.find('.post_body textarea')[0], $('.request.content_type', this.$wurlForm).val(), {})
55
- this.responseBodyMirror = mirror(this.$wurlForm.find('.response.body textarea')[0], $('.response.content_type', this.$wurlForm).val(), { "readOnly": true, "lineNumbers":true});
56
-
57
- $('.give_it_a_wurl', this.$wurlForm).click(function (event) {
58
- event.preventDefault();
59
- self.sendWurl();
60
- });
61
- $('.add_header', this.$wurlForm).click(function () {
62
- self.addInputs('header');
63
- });
64
-
65
- $('.add_param', this.$wurlForm).click(function () {
66
- self.addInputs('param');
67
- });
68
-
69
- $('.delete_header', this.$wurlForm).live('click', function (e) {
70
- self.deleteHeader(this);
71
- });
72
-
73
- $('.delete_param', this.$wurlForm).live('click', function (e) {
74
- self.deleteParam(this);
75
- });
76
-
77
- $(".trash_headers", this.$wurlForm).click(function () {
78
- self.trashHeaders();
79
- });
80
-
81
- $(".trash_queries", self.$wurlForm).click(function () {
82
- self.trashQueries();
83
- });
84
-
85
- $('.header_pair input.value', this.$wurlForm).live('focusin', (function () {
86
- if ($('.header_pair:last input', self.$wurlForm).val() != "") {
87
- self.addInputs('header');
88
- }
89
- }));
90
-
91
- $('.param_pair input.value', this.$wurlForm).live('focusin', (function () {
92
- if ($('.param_pair:last input', self.$wurlForm).val() != "") {
93
- self.addInputs('param');
94
- }
95
- }));
96
-
97
- $('.url select', this.$wurlForm).change(function () {
98
- self.updateBodyInput();
99
- });
100
-
101
- $(".header_pair input.key", this.$wurlForm).livequery(function () {
102
- $(this).autocomplete({source:headers});
103
- });
104
-
105
- $(".clear_fields", this.$wurlForm).click(function () {
106
- $("input[type=text], textarea", self.$wurlForm).val("");
107
- self.trashHeaders();
108
- self.trashQueries();
109
- });
110
-
111
- this.addInputs = function (type) {
112
- var $fields = $('.' + type + '_pair', this.$wurlForm).first().clone();
113
- $fields.children('input').val("").attr('disabled', false);
114
- $fields.hide().appendTo(this.$wurlForm.find('.' + type + 's')).slideDown('fast');
115
- };
116
-
117
- this.deleteHeader = function (element) {
118
- var $fields = $(element).closest(".header_pair");
119
- $fields.slideUp(function () {
120
- $fields.remove();
121
- });
122
- };
123
-
124
- this.deleteParam = function (element) {
125
- var $fields = $(element).closest(".param_pair");
126
- $fields.slideUp(function () {
127
- $paramFields.remove();
128
- });
129
- };
130
-
131
- this.trashHeaders = function () {
132
- $(".header_pair:visible", self.$wurlForm).each(function (i, element) {
133
- $(element).slideUp(function () {
134
- $(element).remove();
135
- });
136
- });
137
- this.addInputs('header');
138
- };
139
-
140
- this.trashQueries = function () {
141
- $(".param_pair:visible", self.$wurlForm).each(function (i, element) {
142
- $(element).slideUp(function () {
143
- $(element).remove();
144
- });
145
- });
146
- this.addInputs('param');
147
- };
148
-
149
- this.updateBodyInput = function () {
150
- var method = $('#wurl_request_method', self.$wurlForm).val();
151
- if ($.inArray(method, ["PUT", "POST", "DELETE"]) > -1) {
152
- $('#wurl_request_body', self.$wurlForm).attr('disabled', false).removeClass('textarea_disabled');
153
- } else {
154
- $('#wurl_request_body', self.$wurlForm).attr('disabled', true).addClass('textarea_disabled');
155
- }
156
- };
157
- this.updateBodyInput();
158
-
159
- this.makeBasicAuth = function () {
160
- var user = $('#wurl_basic_auth_user', this.$wurlForm).val();
161
- var password = $('#wurl_basic_auth_password', this.$wurlForm).val();
162
- var token = user + ':' + password;
163
- var hash = $.base64.encode(token);
164
- return "Basic " + hash;
165
- };
166
-
167
- this.queryParams = function () {
168
- var toReturn = [];
169
- $(".param_pair:visible", self.$wurlForm).each(function (i, element) {
170
- paramKey = $(element).find('input.key').val();
171
- paramValue = $(element).find('input.value').val();
172
- if (paramKey.length && paramValue.length) {
173
- toReturn.push(paramKey + '=' + paramValue);
174
- }
175
- });
176
- return toReturn.join("&");
177
- };
178
-
179
- this.getData = function () {
180
- var method = $('#wurl_request_method', self.$wurlForm).val();
181
- if ($.inArray(method, ["PUT", "POST", "DELETE"]) > -1) {
182
- self.requestBodyMirror.save();
183
- return self.requestBodyMirror.getValue();
184
- } else {
185
- return self.queryParams();
186
- }
187
- };
188
-
189
- this.url = function () {
190
- var url = $('#wurl_request_url', self.$wurlForm).val();
191
- var method = $('#wurl_request_method', self.$wurlForm).val();
192
- var params = self.queryParams();
193
- if ($.inArray(method, ["PUT", "POST", "DELETE"]) > -1 && params.length) {
194
- url += "?" + params;
195
- }
196
- return url[0] == '/' ? url : '/' + url;
197
- };
198
-
199
- this.sendWurl = function () {
200
- $.ajax({
201
- beforeSend:function (req) {
202
- $(".header_pair:visible", self.$wurlForm).each(function (i, element) {
203
- headerKey = $(element).find('input.key').val();
204
- headerValue = $(element).find('input.value').val();
205
- req.setRequestHeader(headerKey, headerValue);
206
- });
207
- req.setRequestHeader('Authorization', self.makeBasicAuth());
208
- },
209
- type:$('#wurl_request_method', self.$wurlForm).val(),
210
- url:this.url(),
211
- data:this.getData(),
212
- complete:function (jqXHR) {
213
- var $status = $('.response.status', self.$wurlForm);
214
- $status.html(jqXHR.status + ' ' + jqXHR.statusText);
215
-
216
- $('.response.headers', self.$wurlForm).html(jqXHR.getAllResponseHeaders());
217
-
218
- contentType = jqXHR.getResponseHeader("content-type");
219
- if (contentType.indexOf('json') >= 0 && jqXHR.responseText.length > 1) {
220
- self.responseBodyMirror.setValue(JSON.stringify(JSON.parse(jqXHR.responseText), undefined, 2));
221
- self.responseBodyMirror.setOption('mode', 'javascript');
222
- self.responseBodyMirror.setOption('json', true);
223
- } else if (contentType.indexOf('javascript') >= 0) {
224
- self.responseBodyMirror.setValue(jqXHR.responseText);
225
- self.responseBodyMirror.setOption('mode', 'javascript');
226
- } else if (contentType.indexOf('xml') >= 0) {
227
- self.responseBodyMirror.setValue(jqXHR.responseText);
228
- self.responseBodyMirror.setOption('mode', 'xml');
229
- } else {
230
- self.responseBodyMirror.setValue(jqXHR.responseText);
231
- self.responseBodyMirror.setOption('mode', 'htmlmixed');
232
- }
233
- $('.response', self.$wurlForm).effect("highlight", {}, 3000);
234
- $('html,body').animate({ scrollTop:$('a.response_anchor', self.$wurlForm).offset().top }, { duration:'slow', easing:'swing'});
235
- }
236
- });
237
- };
238
- }
239
-
240
- $(function () {
241
- $('.wurl_form').each(function (index, wurlForm) {
242
- wurl = new Wurl(wurlForm);
243
- });
244
-
245
- var $textAreas = $('.request.body textarea');
246
- $textAreas.each(function(i, textarea) {
247
- var contentType = $(textarea).parents('div.request').find('.request.content_type').val();
248
- mirror(textarea, contentType, {"readOnly":true, "lineNumbers": true});
249
- });
250
- });