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 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
- $("a.show-api").click(function(e) {
86
+ $("#list-api-div a").click(function(e) {
75
87
  e.preventDefault();
76
88
 
77
- $("a.show-api").parent().removeClass("active");
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() {
@@ -74,7 +74,7 @@ legend {
74
74
  text-align: right;
75
75
  }
76
76
 
77
- .breadcrumb-controller {
77
+ .breadcrumb-parent {
78
78
  font-weight: bold;
79
79
  color: $colour_grey;
80
80
  }
@@ -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
@@ -0,0 +1,9 @@
1
+ <ul class="breadcrumb">
2
+ <li class="breadcrumb-parent"><%= parent %><span class="divider">/</span></li>
3
+ <li>
4
+ <div class="label-api">
5
+ <span class="label label-<%= label_type %>"><%= label %></span>
6
+ </div>
7
+ <strong><%= current %></strong>
8
+ </li>
9
+ </ul>
@@ -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 class="show-api" href="<%= route_path(route[:id]) %>">
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
- <ul class="breadcrumb">
2
- <li class="breadcrumb-controller"><%= @route[:reqs][:controller].humanize %><span class="divider">/</span></li>
3
- <li>
4
- <div class="label-api">
5
- <span class="label label-important"><%= @route[:verb] %></span>
6
- </div>
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] %>
@@ -1,5 +1,7 @@
1
1
  ApiTaster::Engine.routes.draw do
2
- resources :routes, :only => [:index, :show]
2
+ resources :routes, :only => [:index, :show] do
3
+ get :obsolete_definitions, :on => :collection
4
+ end
3
5
 
4
6
  root :to => 'routes#index'
5
7
  end
@@ -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 = Rails.application.routes
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
@@ -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
- Route.inputs[route[:id]] ||= []
26
- Route.inputs[route[:id]] << params
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
@@ -2,6 +2,7 @@ module ApiTaster
2
2
  class Route
3
3
  cattr_accessor :route_set
4
4
  cattr_accessor :inputs
5
+ cattr_accessor :obsolete_definitions
5
6
 
6
7
  class << self
7
8
  def routes
@@ -1,3 +1,3 @@
1
1
  module ApiTaster
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -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
@@ -9,6 +9,10 @@ Rails.application.routes.draw do
9
9
  end
10
10
 
11
11
  ApiTaster.routes do
12
+ get '/i_dont_exist_anymore', {
13
+ :hello => 'world'
14
+ }
15
+
12
16
  get '/users'
13
17
 
14
18
  post '/users', {
@@ -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.2.2
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: -3781747277784541610
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: -3781747277784541610
363
+ hash: 2945703428300743977
362
364
  requirements: []
363
365
  rubyforge_project:
364
366
  rubygems_version: 1.8.24