grep_routes 0.1.0 → 0.1.1

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/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