api_taster 0.2.2 → 0.3.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.
- data/README.md +6 -0
- data/app/assets/javascripts/api_taster/app.js +14 -2
- data/app/assets/stylesheets/api_taster/layout.css.scss +1 -1
- data/app/controllers/api_taster/routes_controller.rb +5 -0
- data/app/views/api_taster/routes/_breadcrumb.html.erb +9 -0
- data/app/views/api_taster/routes/_undefined_route.html.erb +2 -0
- data/app/views/api_taster/routes/index.html.erb +12 -1
- data/app/views/api_taster/routes/obsolete_definitions.html.erb +18 -0
- data/app/views/api_taster/routes/show.html.erb +6 -9
- data/config/routes.rb +3 -1
- data/lib/api_taster.rb +3 -2
- data/lib/api_taster/mapper.rb +10 -2
- data/lib/api_taster/route.rb +1 -0
- data/lib/api_taster/version.rb +1 -1
- data/spec/controllers/api_taster/routes_controller_spec.rb +6 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/mapper_spec.rb +19 -0
- metadata +5 -3
data/README.md
CHANGED
@@ -69,6 +69,12 @@ end
|
|
69
69
|
|
70
70
|
That's it! Enjoy! :)
|
71
71
|
|
72
|
+
## Obsolete / Mismatched Route Definitions Detection
|
73
|
+
|
74
|
+
APIs evolve - especially during the development stage. To keep `ApiTaster.routes` in sync with your route definitions, API Taster provides a warning page that shows you the definitions that are obsolete/mismatched therefore you could correct or remove them.
|
75
|
+
|
76
|
+

|
77
|
+
|
72
78
|
## Use with an Engine
|
73
79
|
|
74
80
|
Rails Engines are largely self contained and separated from your main app. Therefore, to use API Taster with an Engine, you would need some extra efforts:
|
@@ -1,17 +1,23 @@
|
|
1
1
|
var ApiTaster = {
|
2
|
+
|
2
3
|
formAction: '',
|
4
|
+
|
3
5
|
disableUrlParams: function() {
|
4
6
|
$("fieldset[ref=url-params] input").prop("disabled", true);
|
5
7
|
},
|
8
|
+
|
6
9
|
enableUrlParams: function() {
|
7
10
|
$("fieldset[ref=url-params] input").prop("disabled", false);
|
8
11
|
},
|
12
|
+
|
9
13
|
storeFormActionFor: function(form) {
|
10
14
|
ApiTaster.formAction = form.attr("action")
|
11
15
|
},
|
16
|
+
|
12
17
|
restoreFormActionFor: function(form) {
|
13
18
|
$(form).attr("action", ApiTaster.formAction);
|
14
19
|
},
|
20
|
+
|
15
21
|
detectContentType: function(response) {
|
16
22
|
var contentType = response.getResponseHeader("Content-Type");
|
17
23
|
var detectedContentType = null
|
@@ -22,9 +28,11 @@ var ApiTaster = {
|
|
22
28
|
|
23
29
|
return detectedContentType;
|
24
30
|
}
|
31
|
+
|
25
32
|
};
|
26
33
|
|
27
34
|
$.fn.extend({
|
35
|
+
|
28
36
|
replaceUrlParams: function(params) {
|
29
37
|
var form = this;
|
30
38
|
|
@@ -43,6 +51,7 @@ $.fn.extend({
|
|
43
51
|
}
|
44
52
|
});
|
45
53
|
},
|
54
|
+
|
46
55
|
enableNavTabsFor: function(contentElement) {
|
47
56
|
var container = this;
|
48
57
|
|
@@ -56,6 +65,7 @@ $.fn.extend({
|
|
56
65
|
$(contentElement + "[ref=" + $(this).attr("id") + "]", container).show();
|
57
66
|
});
|
58
67
|
},
|
68
|
+
|
59
69
|
showNavTab: function(name) {
|
60
70
|
$("ul.nav-tabs li", this).removeClass("active");
|
61
71
|
$("ul.nav-tabs li a#response-" + name, this).parent().show().addClass("active");
|
@@ -64,17 +74,19 @@ $.fn.extend({
|
|
64
74
|
|
65
75
|
return $("pre[ref=response-" + name + "]", this).show();
|
66
76
|
},
|
77
|
+
|
67
78
|
displayOnlySelectedParamsFieldset: function() {
|
68
79
|
$("fieldset", this).hide();
|
69
80
|
$("fieldset[ref=" + $("ul.nav-tabs li.active a").attr("id") + "]", this).show();
|
70
81
|
}
|
82
|
+
|
71
83
|
});
|
72
84
|
|
73
85
|
jQuery(function($) {
|
74
|
-
$("
|
86
|
+
$("#list-api-div a").click(function(e) {
|
75
87
|
e.preventDefault();
|
76
88
|
|
77
|
-
$(
|
89
|
+
$(this).parent().siblings().removeClass("active");
|
78
90
|
$(this).parent().addClass("active");
|
79
91
|
|
80
92
|
$("#show-api-div .div-container").load(this.href, function() {
|
@@ -2,11 +2,16 @@ module ApiTaster
|
|
2
2
|
class RoutesController < ApplicationController
|
3
3
|
def index
|
4
4
|
@routes = Route.grouped_routes
|
5
|
+
@has_obsolete_definitions = Route.obsolete_definitions.size > 0
|
5
6
|
end
|
6
7
|
|
7
8
|
def show
|
8
9
|
@route = Route.find(params[:id])
|
9
10
|
@inputs = Route.inputs_for(@route)
|
10
11
|
end
|
12
|
+
|
13
|
+
def obsolete_definitions
|
14
|
+
@obsolete_definitions = Route.obsolete_definitions
|
15
|
+
end
|
11
16
|
end
|
12
17
|
end
|
@@ -2,6 +2,8 @@
|
|
2
2
|
<p><strong><%= "Route '#{route[:verb]} #{route[:path]}' is undefined." %></strong></p>
|
3
3
|
<p>Please define this route in <code>routes.rb</code>:</p>
|
4
4
|
<pre class="prettyprint lang-rb">ApiTaster.routes do
|
5
|
+
|
5
6
|
<%= route[:verb].downcase %> '<%= route[:path] %>', {}
|
7
|
+
|
6
8
|
end</pre>
|
7
9
|
</div>
|
@@ -2,11 +2,22 @@
|
|
2
2
|
<div id="list-api-div" class="span5">
|
3
3
|
<div class="div-container">
|
4
4
|
<ul class="well nav nav-list">
|
5
|
+
<% if @has_obsolete_definitions %>
|
6
|
+
<li class="nav-header">Information</li>
|
7
|
+
<li>
|
8
|
+
<a href="<%= obsolete_definitions_routes_path %>">
|
9
|
+
<div class="label-api">
|
10
|
+
<span class="label label-warning">Warning</span>
|
11
|
+
</div>
|
12
|
+
Obsolete Definitions Detected
|
13
|
+
</a>
|
14
|
+
</li>
|
15
|
+
<% end %>
|
5
16
|
<% @routes.each do |controller, routes| %>
|
6
17
|
<li class="nav-header"><%= controller %></li>
|
7
18
|
<% routes.each do |route| %>
|
8
19
|
<li>
|
9
|
-
<a
|
20
|
+
<a href="<%= route_path(route[:id]) %>">
|
10
21
|
<div class="label-api label-api-full">
|
11
22
|
<span class="label label-important"><%= route[:verb] %></span>
|
12
23
|
</div>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%= render 'breadcrumb',
|
2
|
+
:parent => 'Information',
|
3
|
+
:current => 'Obsolete Definitions Detected',
|
4
|
+
:label => 'Warning',
|
5
|
+
:label_type => 'warning'
|
6
|
+
%>
|
7
|
+
|
8
|
+
<div class="alert alert-error">
|
9
|
+
<p><strong>The following route definitions are found within <code>ApiTaster.routes</code> but they are not defined in your routes. Please feel free to correct or remove them.</strong></p>
|
10
|
+
|
11
|
+
<pre class="prettyprint lang-rb">ApiTaster.routes do
|
12
|
+
|
13
|
+
<% @obsolete_definitions.each do |route| %>
|
14
|
+
<%= route[:verb].downcase %> '<%= route[:path] %>'<%= ", #{route[:params]}" if route[:params].present? %>
|
15
|
+
|
16
|
+
<% end %>
|
17
|
+
end</pre>
|
18
|
+
</div>
|
@@ -1,12 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
<strong><%= @route[:path] %></strong>
|
8
|
-
</li>
|
9
|
-
</ul>
|
1
|
+
<%= render 'breadcrumb',
|
2
|
+
:parent => @route[:reqs][:controller].humanize,
|
3
|
+
:current => @route[:path],
|
4
|
+
:label => @route[:verb],
|
5
|
+
:label_type => 'important'
|
6
|
+
%>
|
10
7
|
|
11
8
|
<% if @inputs.is_a?(Hash) && @inputs.has_key?(:undefined) %>
|
12
9
|
<%= render 'undefined_route', :route => @inputs[:undefined] %>
|
data/config/routes.rb
CHANGED
data/lib/api_taster.rb
CHANGED
@@ -6,8 +6,9 @@ require 'api_taster/form_builder'
|
|
6
6
|
|
7
7
|
module ApiTaster
|
8
8
|
def self.routes(&block)
|
9
|
-
Route.route_set
|
10
|
-
Route.inputs
|
9
|
+
Route.route_set = Rails.application.routes
|
10
|
+
Route.inputs = {}
|
11
|
+
Route.obsolete_definitions = []
|
11
12
|
Mapper.instance_eval(&block)
|
12
13
|
end
|
13
14
|
end
|
data/lib/api_taster/mapper.rb
CHANGED
@@ -22,8 +22,16 @@ module ApiTaster
|
|
22
22
|
def map_method(method, path, params)
|
23
23
|
route = Route.find_by_verb_and_path(method, path)
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
if route.nil?
|
26
|
+
Route.obsolete_definitions << {
|
27
|
+
:verb => method,
|
28
|
+
:path => path,
|
29
|
+
:params => params
|
30
|
+
}
|
31
|
+
else
|
32
|
+
Route.inputs[route[:id]] ||= []
|
33
|
+
Route.inputs[route[:id]] << params
|
34
|
+
end
|
27
35
|
end
|
28
36
|
end
|
29
37
|
end
|
data/lib/api_taster/route.rb
CHANGED
data/lib/api_taster/version.rb
CHANGED
@@ -17,5 +17,11 @@ module ApiTaster
|
|
17
17
|
assigns(:route).should be_kind_of(Route)
|
18
18
|
assigns(:inputs).should be_kind_of(Array)
|
19
19
|
end
|
20
|
+
|
21
|
+
it "#obsolete_definitions" do
|
22
|
+
get :obsolete_definitions, :use_route => :api_taster
|
23
|
+
|
24
|
+
assigns(:obsolete_definitions).should be_kind_of(Array)
|
25
|
+
end
|
20
26
|
end
|
21
27
|
end
|
data/spec/dummy/config/routes.rb
CHANGED
data/spec/mapper_spec.rb
CHANGED
@@ -2,6 +2,25 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module ApiTaster
|
4
4
|
describe Mapper do
|
5
|
+
context "non-existing routes" do
|
6
|
+
before(:all) do
|
7
|
+
routes = ActionDispatch::Routing::RouteSet.new
|
8
|
+
routes.draw do
|
9
|
+
# nothing
|
10
|
+
end
|
11
|
+
|
12
|
+
ApiTaster.routes do
|
13
|
+
get '/dummy_route'
|
14
|
+
end
|
15
|
+
|
16
|
+
Route.route_set = routes
|
17
|
+
end
|
18
|
+
|
19
|
+
it "records obsolete definitions" do
|
20
|
+
Route.obsolete_definitions.first[:path].should == '/dummy_route'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
5
24
|
before(:all) do
|
6
25
|
Rails.application.routes.draw { resources :dummy_users }
|
7
26
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_taster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -181,10 +181,12 @@ files:
|
|
181
181
|
- app/controllers/api_taster/application_controller.rb
|
182
182
|
- app/controllers/api_taster/routes_controller.rb
|
183
183
|
- app/helpers/api_taster/application_helper.rb
|
184
|
+
- app/views/api_taster/routes/_breadcrumb.html.erb
|
184
185
|
- app/views/api_taster/routes/_param_form_element.html.erb
|
185
186
|
- app/views/api_taster/routes/_param_form_legend.html.erb
|
186
187
|
- app/views/api_taster/routes/_undefined_route.html.erb
|
187
188
|
- app/views/api_taster/routes/index.html.erb
|
189
|
+
- app/views/api_taster/routes/obsolete_definitions.html.erb
|
188
190
|
- app/views/api_taster/routes/show.html.erb
|
189
191
|
- app/views/layouts/api_taster/application.html.erb
|
190
192
|
- config/routes.rb
|
@@ -349,7 +351,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
349
351
|
version: '0'
|
350
352
|
segments:
|
351
353
|
- 0
|
352
|
-
hash:
|
354
|
+
hash: 2945703428300743977
|
353
355
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
354
356
|
none: false
|
355
357
|
requirements:
|
@@ -358,7 +360,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
358
360
|
version: '0'
|
359
361
|
segments:
|
360
362
|
- 0
|
361
|
-
hash:
|
363
|
+
hash: 2945703428300743977
|
362
364
|
requirements: []
|
363
365
|
rubyforge_project:
|
364
366
|
rubygems_version: 1.8.24
|