grep_routes 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grep_routes (0.0.6)
4
+ grep_routes (0.1.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/grep_routes.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
  $:.push File.expand_path("../lib", __FILE__)
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "grep_routes"
5
- s.version = "0.1.0"
5
+ s.version = "0.1.1"
6
6
  s.authors = ["Tyler Montgomery"]
7
7
  s.email = ["tyler.a.montgomery@gmail.com"]
8
8
  s.homepage = "http://github.com/ubermajestix/grep_routes"
data/lib/grep_routes.rb CHANGED
@@ -9,6 +9,7 @@ end
9
9
  require 'active_support'
10
10
  require 'active_support/core_ext/hash/reverse_merge'
11
11
  require 'active_support/core_ext/enumerable'
12
+ require 'active_support/inflector'
12
13
  require 'grep_routes_mock_rack_app'
13
14
 
14
15
  # See if the user has the 3.2 or 3.1 version of actionpack for action_dispatch.
@@ -30,14 +31,20 @@ class GrepRoutes
30
31
 
31
32
  attr_reader :path_to_routes_file
32
33
  attr_reader :route_file
33
- attr_reader :class_name
34
+ attr_reader :rails_class
34
35
  attr_reader :pattern
36
+ attr_reader :classes
37
+ attr_reader :classes_with_methods
38
+ attr_reader :eval_failures
35
39
 
36
40
  def initialize(path_to_routes_file)
37
41
  @path_to_routes_file = path_to_routes_file
38
- @route_file = File.read(path_to_routes_file)
39
- @class_name = route_file.match(/(\w+)::Application\.routes\.draw/)[1]
42
+ @route_file = ""
43
+ File.open(path_to_routes_file){|f| f.each_line{|l| @route_file << l unless l.strip[0]=='#' }}
44
+ @rails_class = route_file.match(/(\w+)::Application\.routes\.draw/)[1]
45
+ @eval_failures = 0
40
46
  self.init_rails_class
47
+ self.init_other_classes
41
48
  end
42
49
 
43
50
  # To make this fast we don't load your rails app or any of your gems.
@@ -56,8 +63,57 @@ class GrepRoutes
56
63
  end
57
64
 
58
65
  def rails_app
59
- Object.const_set(class_name,Module.new) unless Object.const_defined?(class_name)
60
- Object.const_get(class_name,Module.new)
66
+ Object.const_set(rails_class,Module.new) unless Object.const_defined?(rails_class)
67
+ Object.const_get(rails_class,Module.new)
68
+ end
69
+
70
+ def init_other_classes
71
+ find_classes
72
+ find_classes_with_methods
73
+ classes.each do |class_name|
74
+ define_objects(class_name)
75
+ end
76
+ # This is causing problems: 'Stack level too deep' during eval, the retry will
77
+ # catch any undefined methods and define them on the right class
78
+ # classes_with_methods.each do |class_and_method|
79
+ # # define_methods(*class_and_method)
80
+ # end
81
+ end
82
+
83
+ def find_classes
84
+ @classes = route_file.scan(/([A-Z][a-zA-Z0-9::]*)/).flatten.reject{|c| c.match(rails_class) || c.match("Rails") }
85
+ end
86
+
87
+ def find_classes_with_methods
88
+ match = route_file.scan(/([A-Z][a-zA-Z0-9::]*)\.([_a-z]+[_a-z0-9_<>=~@\[\]]*[=!\?]?)/)
89
+ match.reject!{|m| m.first.match(rails_class) || m.first.match("Rails") }
90
+ # parse out the first method if there's a chain
91
+ # TODO deal with method chains like `app.rack.server`
92
+ match.each{|m| m[1] = m.last.split(".").first}
93
+ @classes_with_methods = match
94
+ end
95
+
96
+ def define_objects(class_name)
97
+ objects = class_name.split("::")
98
+ rack_class = objects.pop
99
+ last_object = Object
100
+ objects.each do |obj|
101
+ last_object.const_set(obj, Module.new) unless last_object.const_defined?(obj)
102
+ last_object = last_object.const_get(obj)
103
+ end
104
+ make_rackapp(last_object, rack_class)
105
+ end
106
+
107
+ # TODO there has got to be a better way to do this!
108
+ def define_methods(class_name, method_name)
109
+ class_name.constantize.class_eval do
110
+ method_to_eval = <<-method_to_eval
111
+ def self.#{method_name}
112
+ GrepRoutesMockRackApp.new
113
+ end
114
+ method_to_eval
115
+ eval(method_to_eval)
116
+ end
61
117
  end
62
118
 
63
119
  def make_rackapp(mod, obj)
@@ -66,44 +122,25 @@ class GrepRoutes
66
122
 
67
123
  # This evals the routes file. After this method is called the RouteSet will
68
124
  # have all of our routes inside it.
69
-
70
125
  def eval_routes
71
- # no_method_retries = 3
72
126
  begin
73
127
  eval(route_file)
74
128
  # If a method is not defined on a class, we define it and try again
75
129
  rescue NoMethodError => e
130
+ @eval_failures += 1
76
131
  match = e.message.match(/undefined method `(.+)' for (.+):Class/)
77
132
  undefined_method = match[1]
78
- # TODO there has got to be a better way to do this!
79
- obj = Object.const_get(match[2], Class.new).class_eval do
80
- method_to_eval = <<-method_to_eval
81
- def self.#{undefined_method}
82
- GrepRoutesMockRackApp.new
83
- end
84
- method_to_eval
85
- eval(method_to_eval)
86
- end
133
+ define_methods(match[2], undefined_method)
87
134
  retry
88
135
  # If a class is not defined we define it and try again
89
136
  rescue NameError => e
137
+ @eval_failures += 1
90
138
  class_name = e.message.match(/uninitialized constant (.+)$/)[1].gsub("GrepRoutes::", '')
91
139
  define_objects(class_name)
92
140
  retry
93
141
  end
94
142
  end
95
143
 
96
- def define_objects(class_name)
97
- objects = class_name.split("::")
98
- rack_class = objects.pop
99
- last_object = Object
100
- objects.each do |obj|
101
- last_object.const_set(obj, Module.new) unless last_object.const_defined?(obj)
102
- last_object = last_object.const_get(obj)
103
- end
104
- make_rackapp(last_object, rack_class)
105
- end
106
-
107
144
  # A shortcut to the RouteSet we defined in init_rails_class.
108
145
  def route_set
109
146
  rails_app.const_get('Application', Class.new).routes
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'finding classes in routes file' do
4
+ subject do
5
+ # The initialization loades up classes and classes_with_methods
6
+ GrepRoutes.new('./spec/fixtures/routes_with_two_classes.rb')
7
+ end
8
+
9
+ it "should find two classes excluding the Rails application class" do
10
+ subject.classes.length.must_equal 2
11
+ end
12
+
13
+ it "should find one class that has a method defined on it" do
14
+ subject.classes_with_methods.length.must_equal 1
15
+ end
16
+
17
+ it "curiously has to define methods on GrepRoutesMockRackApp" do
18
+ subject.eval_routes
19
+ subject.eval_failures.must_equal 1
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ SomeRailsApp::Application.routes.draw do
2
+ resources :user
3
+ mount Someapp, at: '/some/app'
4
+ mount Another::App.server!, at: '/another'
5
+ end
@@ -24,4 +24,8 @@ describe GrepRoutes do
24
24
  subject.routes.map{|r| r[:path]}.must_include "/server/new"
25
25
  end
26
26
 
27
+ it "should not have any eval failures and be fast" do
28
+ subject.eval_failures.must_equal 0
29
+ end
30
+
27
31
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grep_routes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-25 00:00:00.000000000 Z
12
+ date: 2012-02-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: &70270111676060 !ruby/object:Gem::Requirement
16
+ requirement: &70366093883200 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '3.1'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70270111676060
24
+ version_requirements: *70366093883200
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: actionpack
27
- requirement: &70270111675140 !ruby/object:Gem::Requirement
27
+ requirement: &70366093882280 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '3.1'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70270111675140
35
+ version_requirements: *70366093882280
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: minitest
38
- requirement: &70270111674580 !ruby/object:Gem::Requirement
38
+ requirement: &70366093881740 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: 2.11.2
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70270111674580
46
+ version_requirements: *70366093881740
47
47
  description: Greppin in ur routes
48
48
  email:
49
49
  - tyler.a.montgomery@gmail.com
@@ -62,8 +62,10 @@ files:
62
62
  - lib/grep_routes.rb
63
63
  - lib/grep_routes_mock_rack_app.rb
64
64
  - spec/basic_routes_spec.rb
65
+ - spec/finding_classes_spec.rb
65
66
  - spec/fixtures/routes.rb
66
67
  - spec/fixtures/routes_with_rack_mounts.rb
68
+ - spec/fixtures/routes_with_two_classes.rb
67
69
  - spec/spec_helper.rb
68
70
  - spec/with_rack_mounts_spec.rb
69
71
  homepage: http://github.com/ubermajestix/grep_routes
@@ -92,7 +94,9 @@ specification_version: 3
92
94
  summary: Fast Routes for Rails
93
95
  test_files:
94
96
  - spec/basic_routes_spec.rb
97
+ - spec/finding_classes_spec.rb
95
98
  - spec/fixtures/routes.rb
96
99
  - spec/fixtures/routes_with_rack_mounts.rb
100
+ - spec/fixtures/routes_with_two_classes.rb
97
101
  - spec/spec_helper.rb
98
102
  - spec/with_rack_mounts_spec.rb