api_taster 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
![](http://i.imgur.com/rqYiY.png)
|
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
|