avocado-docs 3.0.10 → 3.1.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 (62) hide show
  1. checksums.yaml +5 -13
  2. data/app/assets/javascripts/avocado/app.coffee +1 -0
  3. data/app/assets/javascripts/avocado/application.js.coffee +1 -18
  4. data/app/assets/javascripts/avocado/avocado-ctrl.coffee +50 -0
  5. data/app/assets/javascripts/avocado/{services/request.js.coffee → factories/request.coffee} +5 -3
  6. data/app/assets/javascripts/avocado/factories/resource.coffee +6 -0
  7. data/app/assets/javascripts/avocado/factories/response.coffee +11 -0
  8. data/app/assets/javascripts/avocado/factories/spec.coffee +27 -0
  9. data/app/assets/javascripts/avocado/filters/request-method-filter.coffee +15 -0
  10. data/app/assets/javascripts/avocado/filters/response-status-filter.coffee +15 -0
  11. data/app/controllers/avocado/specs_controller.rb +32 -2
  12. data/app/views/avocado/specs/index.html.erb +51 -0
  13. data/app/views/layouts/avocado.html.erb +20 -0
  14. data/config/routes.rb +1 -1
  15. data/lib/avocado-docs.rb +33 -15
  16. data/lib/avocado/adapters/base_adapter.rb +36 -0
  17. data/lib/avocado/adapters/cucumber_adapter.rb +15 -0
  18. data/lib/avocado/adapters/minitest_adapter.rb +10 -0
  19. data/lib/avocado/adapters/rspec_adapter.rb +13 -0
  20. data/lib/avocado/controller_patch.rb +24 -0
  21. data/lib/avocado/controller_response.rb +22 -0
  22. data/lib/avocado/cucumber.rb +14 -0
  23. data/lib/avocado/logger.rb +13 -0
  24. data/lib/avocado/minitest.rb +10 -23
  25. data/lib/avocado/rspec.rb +9 -18
  26. data/lib/avocado/serializers/request_serializer.rb +43 -0
  27. data/lib/avocado/serializers/resource_serializer.rb +20 -0
  28. data/lib/avocado/serializers/response_serializer.rb +16 -0
  29. data/lib/avocado/{request_store.rb → storage.rb} +6 -9
  30. data/lib/avocado/uploader.rb +41 -31
  31. data/lib/avocado/version.rb +1 -1
  32. metadata +59 -55
  33. data/app/assets/javascripts/avocado/angular-route.min.js +0 -14
  34. data/app/assets/javascripts/avocado/angular.min.js +0 -235
  35. data/app/assets/javascripts/avocado/app.js.coffee +0 -4
  36. data/app/assets/javascripts/avocado/controllers/avocado_ctrl.js.coffee +0 -93
  37. data/app/assets/javascripts/avocado/md5.js +0 -19
  38. data/app/assets/javascripts/avocado/services/endpoint.js.coffee +0 -23
  39. data/app/assets/javascripts/avocado/services/resource.js.coffee +0 -5
  40. data/app/assets/javascripts/avocado/services/response.js.coffee +0 -9
  41. data/app/assets/javascripts/avocado/ui-utils.min.js +0 -7
  42. data/app/controllers/avocado/avocado_controller.rb +0 -20
  43. data/app/models/avocado/endpoint.rb +0 -13
  44. data/app/models/avocado/parser.rb +0 -56
  45. data/app/models/avocado/request.rb +0 -37
  46. data/app/models/avocado/resource.rb +0 -17
  47. data/app/views/layouts/avocado/avocado.html.erb +0 -15
  48. data/app/views/template.html.erb +0 -46
  49. data/lib/avocado/config.rb +0 -36
  50. data/lib/avocado/controller.rb +0 -26
  51. data/lib/avocado/middleware.rb +0 -37
  52. data/lib/avocado/middleware/defaults.rb +0 -17
  53. data/lib/avocado/middleware/document_if_configuration.rb +0 -12
  54. data/lib/avocado/middleware/document_metadata.rb +0 -14
  55. data/lib/avocado/middleware/example_serialization.rb +0 -10
  56. data/lib/avocado/middleware/ignore_xhr_requests.rb +0 -10
  57. data/lib/avocado/middleware/request_serialization.rb +0 -48
  58. data/lib/avocado/middleware/resource_serialization.rb +0 -20
  59. data/lib/avocado/middleware/response_serialization.rb +0 -20
  60. data/lib/avocado/packages/minitest_package.rb +0 -15
  61. data/lib/avocado/packages/package.rb +0 -23
  62. data/lib/avocado/packages/rspec_package.rb +0 -15
@@ -1,56 +0,0 @@
1
- module Avocado
2
- class Parser
3
-
4
- attr_reader :resources, :endpoints, :requests
5
-
6
- def initialize(json)
7
- @resources = SortedSet.new
8
- @endpoints = Set.new
9
- @requests = Set.new
10
- parse(json)
11
- end
12
-
13
- def resource(name)
14
- @resources.find { |r| r.name == name }
15
- end
16
-
17
- private
18
-
19
- def parse(json)
20
- json.each do |req|
21
- resource = find_or_create_resource_by_name req[:resource][:name]
22
- endpoint = find_or_create_endpoint_by_signature resource, req[:request]
23
- request = instantiate_request_object_from(req)
24
- request.endpoint = endpoint
25
-
26
- if request.unique?(@requests)
27
- endpoint.requests << request
28
- resource.endpoints << endpoint
29
- @resources << resource
30
- @endpoints << endpoint
31
- @requests << request
32
- end
33
- end
34
- end
35
-
36
- def instantiate_request_object_from(params)
37
- Avocado::Request.new \
38
- path: params[:request][:path],
39
- params: params[:request][:params],
40
- headers: params[:request][:headers],
41
- status: params[:response][:status],
42
- body: params[:response][:body],
43
- description: params[:description]
44
- end
45
-
46
- def find_or_create_resource_by_name(name)
47
- resource(name) || Avocado::Resource.new(name: name)
48
- end
49
-
50
- def find_or_create_endpoint_by_signature(resource, request)
51
- signature = "#{request[:method]} #{request[:path]}"
52
- resource.endpoints.find { |e| e.signature == signature } || Avocado::Endpoint.new(signature: signature)
53
- end
54
-
55
- end
56
- end
@@ -1,37 +0,0 @@
1
- module Avocado
2
- class Request
3
- include ActiveModel::Model
4
-
5
- attr_accessor :uid, :url, :path, :params, :status, :body, :headers
6
- attr_accessor :endpoint, :description
7
-
8
- def initialize(*)
9
- super
10
- self.uid = SecureRandom.hex
11
- end
12
-
13
- def ==(other)
14
- other.path == path &&
15
- other.params == params &&
16
- other.status == status &&
17
- other.body == body
18
- end
19
-
20
- def <=>(other)
21
- status <=> other.status
22
- end
23
-
24
- def unique?(requests)
25
- requests.none? { |req| self == req }
26
- end
27
-
28
- def params
29
- @params || {}
30
- end
31
-
32
- def body
33
- @body || {}
34
- end
35
-
36
- end
37
- end
@@ -1,17 +0,0 @@
1
- module Avocado
2
- class Resource
3
- include ActiveModel::Model
4
-
5
- attr_accessor :name, :endpoints
6
-
7
- def initialize(*)
8
- @endpoints = Set.new
9
- super
10
- end
11
-
12
- def <=>(other)
13
- name <=> other.name
14
- end
15
-
16
- end
17
- end
@@ -1,15 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>API Docs</title>
5
- <%= stylesheet_link_tag "avocado/application", media: "all" %>
6
- <%= javascript_include_tag "avocado/application" %>
7
- <%= csrf_meta_tags %>
8
- <script type="text/javascript">
9
- var data = <%= @data.html_safe %>;
10
- </script>
11
- </head>
12
- <body ng-app="avocado" ng-controller="AvocadoCtrl">
13
- <%= yield %>
14
- </body>
15
- </html>
@@ -1,46 +0,0 @@
1
- <div class="top-bar">
2
- <a href="#" id="toggle-filter"><%= image_tag 'avocado/filter-icon.png'%></a>
3
- <select ng-model="selectedResource" ng-change="switchResource()">
4
- <option ng-selected="true">All</option>
5
- <option ng-repeat="endpoint in allEndpoints | unique: 'resource.name' | orderBy: 'resource.name'"/>
6
- {{endpoint.resource.name}}
7
- </option>
8
- </select>
9
- <input type="text" ng-model="query" placeholder="Search..." />
10
- <div class="filters">
11
- <label ng-repeat="filter in filters">
12
- <input type="checkbox" ng-model="filter.selected" value="{{filter.name}}" />
13
- {{filter.name}}
14
- </label>
15
- </div>
16
- </div>
17
- <div class="left-side">
18
- <ul>
19
- <li ng-repeat="endpoint in filteredEndpoints | filter: search" ng-click="chooseEndpoint(endpoint)" ng-class="{ 'active': (endpoint == currentEndpoint) }">
20
- <span class="status-code">{{endpoint.response.statusCode}}</span>
21
- <span class="url">{{endpoint.request.method}} {{endpoint.request.path}}</span>
22
- <span class="description">{{endpoint.description}}</span>
23
- </li>
24
- </ul>
25
- </div>
26
- <div class="right-side">
27
- <div ng-if="currentEndpoint">
28
- <span class="url">{{currentEndpoint.request.method}} {{currentEndpoint.request.path}}</span>
29
- <desc>Request Parameters</desc>
30
- <code class="request-params">
31
- {{currentEndpoint.request.params}}
32
- </code>
33
- <desc>Headers</desc>
34
- <code class="headers">
35
- {{currentEndpoint.request.headers}}
36
- </code>
37
- <desc>Response Status</desc>
38
- <code class="response-status">
39
- {{currentEndpoint.response.statusCode}}
40
- </code>
41
- <desc>Response Body</desc>
42
- <code class="response-body">
43
- {{currentEndpoint.response.body}}
44
- </code>
45
- </div>
46
- </div>
@@ -1,36 +0,0 @@
1
- module Avocado
2
- class Config
3
- class << self
4
-
5
- attr_accessor :url, :headers, :document_if, :json_path, :ignored_params
6
-
7
- def configure(&block)
8
- yield self
9
- end
10
-
11
- def headers
12
- Array(@headers) || []
13
- end
14
-
15
- def document_if
16
- @document_if || -> { true }
17
- end
18
-
19
- def json_path
20
- @json_path || Rails.application.root
21
- end
22
-
23
- def ignored_params
24
- @ignored_params ||= ['controller', 'action']
25
- end
26
-
27
- def reset!
28
- @headers = nil
29
- @document_if = nil
30
- @json_path = nil
31
- @ignored_params = nil
32
- end
33
-
34
- end
35
- end
36
- end
@@ -1,26 +0,0 @@
1
- # This concern gets patched into ActionController::Base during testing
2
- # The after_action will ensure every request gets documented regardless of the
3
- # type of test (controller, integration, etc)
4
- module Avocado
5
- module Controller
6
- extend ActiveSupport::Concern
7
-
8
- included do
9
- prepend_around_action :store_request_and_response_in_avocado
10
- end
11
-
12
- def documentable?
13
- (response.status == 204 && response.body.blank?) || !!JSON.parse(response.body)
14
- rescue
15
- false
16
- end
17
-
18
- def store_request_and_response_in_avocado
19
- yield
20
- ensure
21
- Avocado::RequestStore.instance.reset!
22
- Avocado::RequestStore.instance.store(request, response) if documentable?
23
- end
24
-
25
- end
26
- end
@@ -1,37 +0,0 @@
1
- module Avocado
2
- class Middleware
3
-
4
- attr_accessor :entries
5
-
6
- def initialize
7
- @entries = []
8
- end
9
-
10
- def <<(klass)
11
- @entries << klass
12
- end
13
-
14
- def invoke(*args, &finally)
15
- chain = entries.map(&:new).dup
16
- traversal = -> (continue = true) do
17
- return if !continue
18
- if chain.empty?
19
- finally.call
20
- else
21
- chain.shift.call(*args, &traversal)
22
- end
23
- end
24
- traversal.call
25
- end
26
-
27
- def self.configure(&block)
28
- @chain ||= new
29
- yield @chain
30
- end
31
-
32
- def self.invoke(*args, &block)
33
- @chain.invoke(*args, &block)
34
- end
35
-
36
- end
37
- end
@@ -1,17 +0,0 @@
1
- require 'avocado/middleware/document_metadata'
2
- require 'avocado/middleware/document_if_configuration'
3
- require 'avocado/middleware/request_serialization'
4
- require 'avocado/middleware/response_serialization'
5
- require 'avocado/middleware/resource_serialization'
6
- require 'avocado/middleware/example_serialization'
7
- require 'avocado/middleware/ignore_xhr_requests'
8
-
9
- Avocado::Middleware.configure do |chain|
10
- chain << Avocado::Middleware::DocumentMetadata
11
- chain << Avocado::Middleware::DocumentIfConfiguration
12
- chain << Avocado::Middleware::RequestSerialization
13
- chain << Avocado::Middleware::ResponseSerialization
14
- chain << Avocado::Middleware::ResourceSerialization
15
- chain << Avocado::Middleware::ExampleSerialization
16
- chain << Avocado::Middleware::IgnoreXhrRequests
17
- end
@@ -1,12 +0,0 @@
1
- module Avocado
2
- class Middleware::DocumentIfConfiguration
3
-
4
- # return false if document_if returns false, so it will
5
- # stop the middleware chain and not upload anything
6
- def call(*)
7
- continue = Avocado::Config.document_if.call
8
- yield continue
9
- end
10
-
11
- end
12
- end
@@ -1,14 +0,0 @@
1
- module Avocado
2
- class Middleware::DocumentMetadata
3
-
4
- # return false if the :document metadata is given and is explicitly false
5
- def call(package)
6
- if package.document?
7
- yield
8
- else
9
- yield false
10
- end
11
- end
12
-
13
- end
14
- end
@@ -1,10 +0,0 @@
1
- module Avocado
2
- class Middleware::ExampleSerialization
3
-
4
- def call(package)
5
- Avocado::RequestStore.instance.json[:description] = package.description
6
- yield
7
- end
8
-
9
- end
10
- end
@@ -1,10 +0,0 @@
1
- module Avocado
2
- class Middleware::IgnoreXhrRequests
3
-
4
- # return false and bail if the request is AJAX
5
- def call(package)
6
- yield !package.request.xhr?
7
- end
8
-
9
- end
10
- end
@@ -1,48 +0,0 @@
1
- module Avocado
2
- class Middleware::RequestSerialization
3
-
4
- def call(package)
5
- @request = package.request
6
- Avocado::RequestStore.instance.json.merge! request: serialize(@request)
7
- yield
8
- end
9
-
10
- private
11
-
12
- def serialize(request)
13
- {
14
- method: request.method,
15
- path: request.path,
16
- params: sanitize_params(request.params).to_h,
17
- headers: headers
18
- }
19
- end
20
-
21
- def headers
22
- hash = {}
23
- Avocado::Config.headers.each do |name|
24
- hash[name] = @request.headers.env["HTTP_#{name.tr('-', '_')}".upcase]
25
- end
26
- hash.select { |_, value| !value.nil? }
27
- end
28
-
29
- def sanitize_params(params)
30
- params = params.except(*Avocado::Config.ignored_params.flatten)
31
- deep_replace_file_uploads_with_text(params)
32
- params
33
- end
34
-
35
- def deep_replace_file_uploads_with_text(hash)
36
- hash.each do |k, v|
37
- if v.is_a? Hash
38
- deep_replace_file_uploads_with_text(v)
39
- elsif v.is_a? Array
40
- v.each { |element| deep_replace_file_uploads_with_text(_: element) }
41
- elsif v.respond_to? :eof
42
- hash[k] = '<Multipart File Upload>'
43
- end
44
- end
45
- end
46
-
47
- end
48
- end
@@ -1,20 +0,0 @@
1
- module Avocado
2
- class Middleware::ResourceSerialization
3
-
4
- def call(package)
5
- request = package.request
6
- name = infer_resource_name_from_request(request)
7
- Avocado::RequestStore.instance.json.merge! resource: { name: name }
8
- yield
9
- end
10
-
11
- private
12
-
13
- def infer_resource_name_from_request(request)
14
- controller = request.params[:controller]
15
- name = controller.partition('/').reject(&:blank?).last
16
- name.titleize.split('/').last
17
- end
18
-
19
- end
20
- end
@@ -1,20 +0,0 @@
1
- module Avocado
2
- class Middleware::ResponseSerialization
3
-
4
- def call(package)
5
- response = package.response
6
- Avocado::RequestStore.instance.json.merge! response: serialize(response)
7
- yield
8
- end
9
-
10
- private
11
-
12
- def serialize(response)
13
- {
14
- status: response.status,
15
- body: response.body
16
- }
17
- end
18
-
19
- end
20
- end
@@ -1,15 +0,0 @@
1
- module Avocado
2
- module Packages
3
- class MinitestPackage < Package
4
-
5
- def description
6
- example
7
- end
8
-
9
- def document?
10
- true
11
- end
12
-
13
- end
14
- end
15
- end